From e0e1987dd653d83122ad65d5e45c7f64111c115a Mon Sep 17 00:00:00 2001 From: Brent Shambaugh Date: Sat, 29 May 2021 06:31:18 -0500 Subject: [PATCH 01/38] feat(key-did-resolver): secp256r1 support * commit a temporary file called backup * rebase to april 9th, and bring in desireable changes to may19th * remove tests for null and related functions because they are not needed * Add "bigint-mod-arith": "^3.0.0" to key-did-resolver package.json * add a try and finally blocks for pubKeyBytesToXY add tests to show errors for functions that are dependencies * removed try and finally blocks from secp256r1.ts * refactored code to get linter to pass * simplify TypeError conditional in pubKeyBytesToXY since null loosely equals undefined * add additional tests for malformed did:keys , add comments to secp256r1.ts code * move test for functions in the test file to the end. Clean up and add additional tests to null. Assume this covers undefined. * add tests for undefined case for functions declared for use in test file. Fix functions to allow undefined cases to pass. * modify js-ceramic tsconfig.json to include target of ES2020 to allow for support of BigInt in package key-did-resolver * remove old target for ES2018 js-ceramic in main tsconfig.json, and replace with ES2020 (removing duplicates) * remove target: ES2020 from key-did-resolver package, since it is redundant with parent js-ceramic tsconfig.json * first run at adding comments to src/secp256r1.ts . Incomplete. * added documentation annotations for src/secp256r1.ts. May rewrite after forcing functions to throw custom errors for null and undefined * updated code and tests * updated the tests and code for more specific error responses. This is a work in progress. * update tests and code for publicKeyIntToUint8ArrayPointPair function * updated tests to pass * updated publicKeyIntToUint8ArrayPointPair and publicKeyIntToXY parameter description since redundant with error message * add function with tests to test to see if input is a Uint8Array : testUint8Array * update testUint8Array with typing info to pass linter test * added function to test for hex string * update publicKeyHexToUint8ArrayPointPair with better error checking * updated publicKeyToXY to handle only hex strings and throw and error otherwise * update pubKeyBytesToHex to only allow for Uint8Arrays and throw and error if otherwise * Add error checking for ECPointDecompress so it only allows Uint8Arrays * Add error checking for publicKeyBytesToXY so it only allows Uint8Arrays * Refactor publicKeyIntToXY and publicKeyIntToUint8ArrayPointPair in sec/secp256r1.ts * refactored logic in secp256r1.ts NOT(A AND B) = NOT(A) OR NOT(B) --- packages/key-did-resolver/package.json | 3 +- .../__snapshots__/index.test.ts.snap | 225 ++++++ .../__snapshots__/secp256r1.test.ts.snap | 94 +++ .../src/__tests__/index.test.ts | 44 ++ .../src/__tests__/secp256r1.test.ts | 658 ++++++++++++++++++ packages/key-did-resolver/src/index.ts | 2 + packages/key-did-resolver/src/secp256r1.ts | 272 ++++++++ tsconfig.json | 2 +- 8 files changed, 1298 insertions(+), 2 deletions(-) create mode 100644 packages/key-did-resolver/src/__tests__/__snapshots__/secp256r1.test.ts.snap create mode 100644 packages/key-did-resolver/src/__tests__/secp256r1.test.ts create mode 100644 packages/key-did-resolver/src/secp256r1.ts diff --git a/packages/key-did-resolver/package.json b/packages/key-did-resolver/package.json index c2464742f6..935fdfc9ec 100644 --- a/packages/key-did-resolver/package.json +++ b/packages/key-did-resolver/package.json @@ -30,7 +30,8 @@ "@stablelib/ed25519": "^1.0.1", "multibase": "~4.0.2", "uint8arrays": "^2.0.5", - "varint": "^6.0.0" + "varint": "^6.0.0", + "bigint-mod-arith": "^3.0.0" }, "devDependencies": { "@types/multibase": "~3.1.0", diff --git a/packages/key-did-resolver/src/__tests__/__snapshots__/index.test.ts.snap b/packages/key-did-resolver/src/__tests__/__snapshots__/index.test.ts.snap index 90d68aafcf..8f1a0ffc01 100644 --- a/packages/key-did-resolver/src/__tests__/__snapshots__/index.test.ts.snap +++ b/packages/key-did-resolver/src/__tests__/__snapshots__/index.test.ts.snap @@ -145,3 +145,228 @@ Object { }, } `; + +exports[`Index mapper successfully resolves the document from did 5`] = ` +Object { + "didDocument": Object { + "@context": "https://w3id.org/did/v1", + "assertionMethod": Array [ + "did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ#zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ", + ], + "authentication": Array [ + "did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ#zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ", + ], + "capabilityDelegation": Array [ + "did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ#zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ", + ], + "capabilityInvocation": Array [ + "did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ#zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ", + ], + "id": "did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ", + "verificationMethod": Array [ + Object { + "controller": "did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ", + "id": "did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ#zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ", + "publicKeyJwk": Object { + "crv": "P-256", + "kty": "EC", + "x": "u-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y", + "y": "uHNNnF7isXk_qitI9yNB4PCMY7krXqA224AJq0LByok8", + }, + "type": "JsonWebKey2020", + }, + ], + }, + "didDocumentMetadata": Object {}, + "didResolutionMetadata": Object { + "contentType": "application/did+ld+json", + }, +} +`; + +exports[`Index mapper successfully resolves the document from did 6`] = ` +Object { + "didDocument": Object { + "assertionMethod": Array [ + "did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ#zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ", + ], + "authentication": Array [ + "did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ#zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ", + ], + "capabilityDelegation": Array [ + "did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ#zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ", + ], + "capabilityInvocation": Array [ + "did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ#zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ", + ], + "id": "did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ", + "verificationMethod": Array [ + Object { + "controller": "did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ", + "id": "did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ#zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ", + "publicKeyJwk": Object { + "crv": "P-256", + "kty": "EC", + "x": "u-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y", + "y": "uHNNnF7isXk_qitI9yNB4PCMY7krXqA224AJq0LByok8", + }, + "type": "JsonWebKey2020", + }, + ], + }, + "didDocumentMetadata": Object {}, + "didResolutionMetadata": Object { + "contentType": "application/did+json", + }, +} +`; + +exports[`Index mapper successfully resolves the document from did 7`] = ` +Object { + "didDocument": Object { + "@context": "https://w3id.org/did/v1", + "assertionMethod": Array [ + "did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu#zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu", + ], + "authentication": Array [ + "did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu#zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu", + ], + "capabilityDelegation": Array [ + "did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu#zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu", + ], + "capabilityInvocation": Array [ + "did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu#zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu", + ], + "id": "did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu", + "verificationMethod": Array [ + Object { + "controller": "did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu", + "id": "did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu#zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu", + "publicKeyJwk": Object { + "crv": "P-256", + "kty": "EC", + "x": "uOcPddBMXKURtwbPaZ9SfwEb8vwcvzFufpRwFuXQwf5Y", + "y": "unEA7FjXwRJ8CvUInUeMxIaRDTxUvKysqP2dSGcXZJfY", + }, + "type": "JsonWebKey2020", + }, + ], + }, + "didDocumentMetadata": Object {}, + "didResolutionMetadata": Object { + "contentType": "application/did+ld+json", + }, +} +`; + +exports[`Index mapper successfully resolves the document from did 8`] = ` +Object { + "didDocument": Object { + "assertionMethod": Array [ + "did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu#zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu", + ], + "authentication": Array [ + "did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu#zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu", + ], + "capabilityDelegation": Array [ + "did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu#zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu", + ], + "capabilityInvocation": Array [ + "did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu#zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu", + ], + "id": "did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu", + "verificationMethod": Array [ + Object { + "controller": "did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu", + "id": "did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu#zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu", + "publicKeyJwk": Object { + "crv": "P-256", + "kty": "EC", + "x": "uOcPddBMXKURtwbPaZ9SfwEb8vwcvzFufpRwFuXQwf5Y", + "y": "unEA7FjXwRJ8CvUInUeMxIaRDTxUvKysqP2dSGcXZJfY", + }, + "type": "JsonWebKey2020", + }, + ], + }, + "didDocumentMetadata": Object {}, + "didResolutionMetadata": Object { + "contentType": "application/did+json", + }, +} +`; + +exports[`Index mapper successfully resolves the document from did 9`] = ` +Object { + "didDocument": Object { + "@context": "https://w3id.org/did/v1", + "assertionMethod": Array [ + "did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY#z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", + ], + "authentication": Array [ + "did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY#z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", + ], + "capabilityDelegation": Array [ + "did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY#z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", + ], + "capabilityInvocation": Array [ + "did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY#z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", + ], + "id": "did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", + "verificationMethod": Array [ + Object { + "controller": "did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", + "id": "did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY#z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", + "publicKeyJwk": Object { + "crv": "P-256", + "kty": "EC", + "x": "u-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y", + "y": "uHNNnF7isXk_qitI9yNB4PCMY7krXqA224AJq0LByok8", + }, + "type": "JsonWebKey2020", + }, + ], + }, + "didDocumentMetadata": Object {}, + "didResolutionMetadata": Object { + "contentType": "application/did+ld+json", + }, +} +`; + +exports[`Index mapper successfully resolves the document from did 10`] = ` +Object { + "didDocument": Object { + "assertionMethod": Array [ + "did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY#z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", + ], + "authentication": Array [ + "did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY#z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", + ], + "capabilityDelegation": Array [ + "did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY#z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", + ], + "capabilityInvocation": Array [ + "did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY#z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", + ], + "id": "did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", + "verificationMethod": Array [ + Object { + "controller": "did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", + "id": "did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY#z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", + "publicKeyJwk": Object { + "crv": "P-256", + "kty": "EC", + "x": "u-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y", + "y": "uHNNnF7isXk_qitI9yNB4PCMY7krXqA224AJq0LByok8", + }, + "type": "JsonWebKey2020", + }, + ], + }, + "didDocumentMetadata": Object {}, + "didResolutionMetadata": Object { + "contentType": "application/did+json", + }, +} +`; diff --git a/packages/key-did-resolver/src/__tests__/__snapshots__/secp256r1.test.ts.snap b/packages/key-did-resolver/src/__tests__/__snapshots__/secp256r1.test.ts.snap new file mode 100644 index 0000000000..c4ba23da94 --- /dev/null +++ b/packages/key-did-resolver/src/__tests__/__snapshots__/secp256r1.test.ts.snap @@ -0,0 +1,94 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Secp256r1 mapper successfully resolves the document from did 1`] = ` +Object { + "assertionMethod": Array [ + "did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ#zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ", + ], + "authentication": Array [ + "did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ#zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ", + ], + "capabilityDelegation": Array [ + "did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ#zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ", + ], + "capabilityInvocation": Array [ + "did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ#zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ", + ], + "id": "did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ", + "verificationMethod": Array [ + Object { + "controller": "did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ", + "id": "did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ#zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ", + "publicKeyJwk": Object { + "crv": "P-256", + "kty": "EC", + "x": "u-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y", + "y": "uHNNnF7isXk_qitI9yNB4PCMY7krXqA224AJq0LByok8", + }, + "type": "JsonWebKey2020", + }, + ], +} +`; + +exports[`Secp256r1 mapper successfully resolves the document from did 2`] = ` +Object { + "assertionMethod": Array [ + "did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu#zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu", + ], + "authentication": Array [ + "did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu#zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu", + ], + "capabilityDelegation": Array [ + "did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu#zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu", + ], + "capabilityInvocation": Array [ + "did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu#zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu", + ], + "id": "did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu", + "verificationMethod": Array [ + Object { + "controller": "did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu", + "id": "did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu#zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu", + "publicKeyJwk": Object { + "crv": "P-256", + "kty": "EC", + "x": "uOcPddBMXKURtwbPaZ9SfwEb8vwcvzFufpRwFuXQwf5Y", + "y": "unEA7FjXwRJ8CvUInUeMxIaRDTxUvKysqP2dSGcXZJfY", + }, + "type": "JsonWebKey2020", + }, + ], +} +`; + +exports[`Secp256r1 mapper successfully resolves the document from did 3`] = ` +Object { + "assertionMethod": Array [ + "did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY#z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", + ], + "authentication": Array [ + "did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY#z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", + ], + "capabilityDelegation": Array [ + "did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY#z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", + ], + "capabilityInvocation": Array [ + "did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY#z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", + ], + "id": "did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", + "verificationMethod": Array [ + Object { + "controller": "did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", + "id": "did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY#z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", + "publicKeyJwk": Object { + "crv": "P-256", + "kty": "EC", + "x": "u-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y", + "y": "uHNNnF7isXk_qitI9yNB4PCMY7krXqA224AJq0LByok8", + }, + "type": "JsonWebKey2020", + }, + ], +} +`; diff --git a/packages/key-did-resolver/src/__tests__/index.test.ts b/packages/key-did-resolver/src/__tests__/index.test.ts index 73fe98d92c..e9eb0d0802 100644 --- a/packages/key-did-resolver/src/__tests__/index.test.ts +++ b/packages/key-did-resolver/src/__tests__/index.test.ts @@ -36,7 +36,51 @@ describe('Index mapper', () => { doc = await resolve('did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8', parsedDid, {}, { accept: 'application/did+json' }) expect(doc).toMatchSnapshot() + + parsedDid = { + id: "zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ", + did: 'did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ', + method: "key", + didUrl: 'did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ/some/path', + path: '/some/path' + } + + doc = await resolve('did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ', parsedDid, {}, { accept: 'application/did+ld+json' }) + expect(doc).toMatchSnapshot() + + doc = await resolve('did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ', parsedDid, {}, { accept: 'application/did+json' }) + expect(doc).toMatchSnapshot() + + parsedDid = { + id: "zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu", + did: 'did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu', + method: "key", + didUrl: 'did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu/some/path', + path: '/some/path' + } + + doc = await resolve('did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu', parsedDid, {}, { accept: 'application/did+ld+json' }) + expect(doc).toMatchSnapshot() + + doc = await resolve('did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu', parsedDid, {}, { accept: 'application/did+json' }) + expect(doc).toMatchSnapshot() + + parsedDid = { + id: "z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", + did: 'did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY', + method: "key", + didUrl: 'did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY/some/path', + path: '/some/path' + } + + doc = await resolve('did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY', parsedDid, {}, { accept: 'application/did+ld+json' }) + expect(doc).toMatchSnapshot() + + doc = await resolve('did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY', parsedDid, {}, { accept: 'application/did+json' }) + expect(doc).toMatchSnapshot() + }) + }) diff --git a/packages/key-did-resolver/src/__tests__/secp256r1.test.ts b/packages/key-did-resolver/src/__tests__/secp256r1.test.ts new file mode 100644 index 0000000000..9ec6f21a04 --- /dev/null +++ b/packages/key-did-resolver/src/__tests__/secp256r1.test.ts @@ -0,0 +1,658 @@ +// Brent Shambaugh . 2021. + +import varint from "varint" +import multibase from "multibase" +import * as mapper from "../secp256r1" +import * as u8a from 'uint8arrays' + +describe('Secp256r1 mapper', () => { + + // testing the key from the did:key from the raw public key + it('successfully resolves the document from did', async () => { + const id = "zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ" + + const multicodecPubKey = multibase.decode(id) + varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well + const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) + const doc = await mapper.keyToDidDoc(pubKeyBytes, id) + expect(doc).toMatchSnapshot() + }) + + // testing the key from the did:key from the compressed public key + it('successfully resolves the document from did', async () => { + const id = "zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu" + + const multicodecPubKey = multibase.decode(id) + varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well + const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) + const doc = await mapper.keyToDidDoc(pubKeyBytes, id) + expect(doc).toMatchSnapshot() + }) + + // testing the key from the did:key from the uncompressed public key + it('successfully resolves the document from did', async () => { + const id = "z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY" + + const multicodecPubKey = multibase.decode(id) + varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well + const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) + const doc = await mapper.keyToDidDoc(pubKeyBytes, id) + expect(doc).toMatchSnapshot() + }) + +}) + +test('test a hex string with unexpected input', () => { + const inputPublicKeyHex = ''; + const publicKey_u8a = mapper.testHexString(inputPublicKeyHex); + expect(publicKey_u8a).toEqual(false); +}); + +test('test a hex string with unexpected input : try 2', () => { + const inputPublicKeyHex = 99; + const publicKey_u8a = mapper.testHexString(inputPublicKeyHex); + expect(publicKey_u8a).toEqual(false); +}); + +test('test a hex string shorter than 33 bytes', () => { + const inputPublicKeyHex = 'abc09'; + const publicKey_u8a = mapper.testHexString(inputPublicKeyHex); + expect(publicKey_u8a).toEqual(true); +}); + +test('test testUint8Array with correct input', () => { + const inputCompressedPoint = Uint8Array.from([3,127,35,88,48,221,61,239,167,34,239,26,162,73,214,160,221,187,164,249,144,176,129,117,56,147,63,87,54,64,101,53,66]); + const publicKey_u8a = mapper.testUint8Array(inputCompressedPoint); + expect(publicKey_u8a).toEqual(true); +}); + +test('test testUint8Array with number', () => { + const inputCompressedPoint = 5; + const publicKey_u8a = mapper.testUint8Array(inputCompressedPoint); + expect(publicKey_u8a).toEqual(false); +}); + +test('test testUint8Array with number', () => { + const inputCompressedPoint = 'donkey'; + const publicKey_u8a = mapper.testUint8Array(inputCompressedPoint); + expect(publicKey_u8a).toEqual(false); +}); + +test('expect pubKeyBytesToHex to throw an error for null', () => { + expect(() => { + mapper.pubKeyBytesToHex(null); + }).toThrowError('input must be a Uint8Array'); +}); + +test('expect pubKeyBytesToHex to throw an error for undefined', () => { + expect(() => { + mapper.pubKeyBytesToHex(); + }).toThrowError('input must be a Uint8Array'); +}); + +test('expect pubKeyBytesToHex to throw an error for an unexpected integer', () => { + expect(() => { + mapper.pubKeyBytesToHex(5); + }).toThrowError('input must be a Uint8Array'); +}); + +test('expect pubKeyBytesToHex to throw an error for an unexpected object', () => { + expect(() => { + mapper.pubKeyBytesToHex({x: 6n, y: 5n}); + }).toThrowError('input must be a Uint8Array'); +}); + + +test('expect ECPointDecompress to throw an error for undefined', () => { + expect(() => { + mapper.ECPointDecompress(); + }).toThrowError('input must be a Uint8Array'); +}); + +test('expect ECPointDecompress to throw an error for null', () => { + expect(() => { + mapper.ECPointDecompress(null); + }).toThrowError('input must be a Uint8Array'); +}); + +test('expect ECPointDecompress to throw an error for unexpected input', () => { + expect(() => { + mapper.ECPointDecompress(5); + }).toThrowError('input must be a Uint8Array'); +}); + +test('expect publicKeyIntToXY to throw an error for incorrect type', () => { + expect(() => { + mapper.publicKeyIntToXY(5); + }).toThrowError('Input must be an object with properties x and y'); +}); + +test('expect publicKeyIntToXY to throw an error for {x: null, y: null}', () => { + expect(() => { + mapper.publicKeyIntToXY({x: null, y: null}); + }).toThrowError('Input coordinates must be BigInt'); +}); + +test('expect publicKeyIntToXY to throw an error for {x: undefined, y: undefined}', () => { + expect(() => { + mapper.publicKeyIntToXY(); + }).toThrow(); +}); + + +test('expect publicKeyHextToUint8ArrayPointPair to throw an error for {x: undefined, y: undefined}', () => { + expect(() => { + mapper.publicKeyHexToUint8ArrayPointPair(); + }).toThrowError('input must be string with characters 0-9,A-F,a-f'); +}); + + +test('expect publicKeyHexToUint8ArrayPointPair to throw an error for incorrect type', () => { + expect(() => { + mapper.publicKeyHexToUint8ArrayPointPair(5); + }).toThrowError('input must be string with characters 0-9,A-F,a-f'); +}); + + +test('expect publicKeyHexToUint8ArrayPointPair to throw an error for {x: null, y: null}', () => { + expect(() => { + mapper.publicKeyHexToUint8ArrayPointPair({x: null, y: null}); + }).toThrowError('input must be string with characters 0-9,A-F,a-f'); +}); + +test('expect publicKeyHexToUint8ArrayPointPair to throw an error for {x: undefined, y: undefined}', () => { + expect(() => { + mapper.publicKeyHexToUint8ArrayPointPair({x: undefined, y: undefined}); + }).toThrowError('input must be string with characters 0-9,A-F,a-f'); +}); + +test('expect publicKeyHexToUint8ArrayPointPair to throw an error for null', () => { + expect(() => { + mapper.publicKeyHexToUint8ArrayPointPair(null); + }).toThrowError('input must be string with characters 0-9,A-F,a-f'); +}); + +test('expect publicKeyToXY to throw an error for null', () => { + expect(() => { + mapper.publicKeyToXY(null); + }).toThrowError('input must be string with characters 0-9,A-F,a-f'); +}); + +test('expect publicKeyToXY to throw an error for undefined', () => { + expect(() => { + mapper.publicKeyToXY(); + }).toThrowError('input must be string with characters 0-9,A-F,a-f'); +}); + +test('expect publicKeyToXY to throw an error for a non string', () => { + expect(() => { + mapper.publicKeyToXY(5); + }).toThrowError('input must be string with characters 0-9,A-F,a-f'); +}); + +test('expect publicKeyToXY to throw an error for an invalid hex string', () => { + expect(() => { + mapper.publicKeyToXY('095ty'); + }).toThrowError('input must be string with characters 0-9,A-F,a-f'); +}); + +test('expect publicKeyBytesToXY to throw an error for undefined', () => { + expect(() => { + mapper.pubKeyBytesToXY(); + }).toThrowError('input must be a Uint8Array'); +}); + +test('expect publicKeyBytesToXY to throw an error for null', () => { + expect(() => { + mapper.pubKeyBytesToXY(null); + }).toThrowError('input must be a Uint8Array'); +}); + +test('expect publicKeyBytesToXY to throw an error for and integer input', () => { + expect(() => { + mapper.pubKeyBytesToXY(5); + }).toThrowError('input must be a Uint8Array'); +}); + +test('empty key string to should not evaluate to null, or should it??', () => { + const inputPublicKeyHex = ''; + expect(() => { + mapper.publicKeyHexToUint8ArrayPointPair(inputPublicKeyHex); + }).toThrowError('input must be string with characters 0-9,A-F,a-f'); + }); + +test('test a hex string shorter than 33 bytes', () => { + const inputPublicKeyHex = '36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb6' + const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); + expect(publicKey_u8a).not.toEqual(null); +}); + +test('test a compressed public key in hex with an odd number of characters', () => { + const inputPublicKeyHex = '2f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb6'; + const output = Uint8Array.from([2,249,195,111,137,100,98,51,120,189,192,104,212,188,224,126,209,124,143,164,134,249,172,12,38,19,202,60,140,48, 109, 123, 182]); + const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); + expect(publicKey_u8a).toEqual(output); +}); + +test('test a uncompressed public key in hex to an x,y point with x, and y url encoded with an unsupported prefix', () => { + const inputPublicKeyHex = '03f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb61cd36717b8ac5e4fea8ad23dc8d0783c2318ee4ad7a80db6e0026ad0b072a24f' + const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); + expect(() => { + mapper.pubKeyBytesToXY(publicKey_u8a); + }).toThrowError('Unexpected pubKeyBytes'); +}); + +test('test a compressed public key in hex to an x,y point with x, and y url encoded with an unsupported prefixi: try2', () => { + const inputPublicKeyHex = '05f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb6' + const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); + expect(() => { + mapper.pubKeyBytesToXY(publicKey_u8a); + }).toThrowError('Unexpected pubKeyBytes'); +}); + +test('test a compressed public key in hex to an x,y point with x, and y url encoded with an unsupported prefixi: try3', () => { + const inputPublicKeyHex = '04f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb6'; + const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); + expect(() => { + mapper.pubKeyBytesToXY(publicKey_u8a); + }).toThrowError('Unexpected pubKeyBytes'); +}); + +test('test a compressed public key in hex to an x,y point with x, and y url encoded with an unsupported prefix', () => { + const inputPublicKeyHex = '04f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb6' + const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); + expect(() => { + mapper.pubKeyBytesToXY(publicKey_u8a); + }).toThrowError('Unexpected pubKeyBytes'); +}); + +test('test a compressed public key in hex to an x,y point with x, and y url encoded with an unexpected length', () => { + const inputPublicKeyHex = '0239c3dd74131729446dc1b3da67d49fc046fcbf072fcc5b9fa51c05b974307f9642'; + const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); + expect(() => { + mapper.pubKeyBytesToXY(publicKey_u8a); + }).toThrowError('Unexpected pubKeyBytes'); +}); + +test('test a hex string longer than 65 bytes', () => { + const inputPublicKeyHex = '0704f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb61cd36717b8ac5e4fea8ad23dc8d0783c2318ee4ad7a80db6e0026ad0b072a24f' + const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); + expect(() => { + mapper.pubKeyBytesToXY(publicKey_u8a); + }).toThrowError('Unexpected pubKeyBytes'); +}); + +test('test a hex string longer than 65 bytes: try2', () => { + const inputPublicKeyHex = '04f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb61cd36717b8ac5e4fea8ad23dc8d0783c2318ee4ad7a80db6e0026ad0b072a24f07'; + const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); + expect(() => { + mapper.pubKeyBytesToXY(publicKey_u8a); + }).toThrowError('Unexpected pubKeyBytes'); +}) + +test('test a compressed public key in hex to an x,y point with x, and y url encoded', () => { + const inputPublicKeyHex = '03f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb6' + const output = { + xm: 'u-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y', + ym: 'uHNNnF7isXk_qitI9yNB4PCMY7krXqA224AJq0LByok8' + }; + const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); + const pubKeyBytesToXY = mapper.pubKeyBytesToXY(publicKey_u8a); + expect(pubKeyBytesToXY).toEqual(output); +}); + +test('test a uncompressed public key in hex to an x,y point with x, and y url encoded', () => { + const inputPublicKeyHex = '04f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb61cd36717b8ac5e4fea8ad23dc8d0783c2318ee4ad7a80db6e0026ad0b072a24f' + const output = { + xm: 'u-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y', + ym: 'uHNNnF7isXk_qitI9yNB4PCMY7krXqA224AJq0LByok8' + }; + const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); + const pubKeyBytesToXY = mapper.pubKeyBytesToXY(publicKey_u8a); + expect(pubKeyBytesToXY).toEqual(output); +}); + +test('test a raw public key in hex to an x,y point with x, and y url encoded', () => { + const inputPublicKeyHex = 'f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb61cd36717b8ac5e4fea8ad23dc8d0783c2318ee4ad7a80db6e0026ad0b072a24f' + const output = { + xm: 'u-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y', + ym: 'uHNNnF7isXk_qitI9yNB4PCMY7krXqA224AJq0LByok8' + }; + const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); + const pubKeyBytesToXY = mapper.pubKeyBytesToXY(publicKey_u8a); + expect(pubKeyBytesToXY).toEqual(output); +}); + +test('convert a public key x,y where x and y are integers to an x,y point with x and y base64url encoded', () => { + const ecpoint = { + x: 112971204272793929541699765384018665134067875121047561926148644683187420494774n, + y: 13038276010400560657327464707708345466200402936352359974176190171319880557135n + }; + const output = { + xm: 'u-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y', + ym: 'uHNNnF7isXk_qitI9yNB4PCMY7krXqA224AJq0LByok8' + }; + + const base64urlPoint = mapper.publicKeyIntToXY(ecpoint); + expect(base64urlPoint).toEqual(output); + +}); + + +test('convert raw public key as a hex string into an x,y point with x and y base64url encoded', () => { + const inputPublicKeyHex = 'f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb61cd36717b8ac5e4fea8ad23dc8d0783c2318ee4ad7a80db6e0026ad0b072a24f' + const output = { + xm: 'u-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y', + ym: 'uHNNnF7isXk_qitI9yNB4PCMY7krXqA224AJq0LByok8' + }; + const base64urlPoint = mapper.publicKeyToXY(inputPublicKeyHex); + expect(base64urlPoint).toEqual(output); +}); + +test('expect publicKeyIntToXY to throw an error for incorrect type', () => { + expect(() => { + mapper.publicKeyIntToXY(5); + }).toThrowError('Input must be an object with properties x and y'); +}); + +test('expect publicKeyIntToXY to throw an error for {x: null, y: null}', () => { + expect(() => { + mapper.publicKeyIntToXY({x: null, y: null}); + }).toThrowError('Input coordinates must be BigInt'); +}); + +test('expect publicKeyIntToXY to have properties x and y', () => { + expect(() => { + mapper.publicKeyIntToXY({x: 5n, z: 8n}); + }).toThrowError('Input must have properties x and y'); +}); + +test('expect publicKeyIntToXY to throw an error for {x: undefined, y: undefined}', () => { + expect(() => { + mapper.publicKeyIntToXY(); + }).toThrowError('input cannot be null or undefined.'); +}); + +test('expect publicKeyIntToUint8ArrayPointPair to throw an error for {x: undefined, y: undefined}', () => { + expect(() => { + mapper.publicKeyHexToUint8ArrayPointPair(); + }).toThrowError('input must be string with characters 0-9,A-F,a-f'); +}); + +test('expect publicKeyIntToUint8ArrayPointPair to throw an error for {x: 5, y: 9}', () => { + expect(() => { + mapper.publicKeyIntToUint8ArrayPointPair({x: 5,y: 9}); + }).toThrowError('Input coordinates must be BigInt'); +}); + +test('expect publicKeyIntToUint8ArrayPointPair to throw an error for null', () => { + expect(() => { + mapper.publicKeyIntToUint8ArrayPointPair(null); + }).toThrowError('input cannot be null or undefined.'); +}); + +test('expect publicKeyIntToUint8ArrayPointPair to throw an error for mislabled coordinate properties', () => { + expect(() => { + mapper.publicKeyIntToUint8ArrayPointPair({x: 5n, z: 7n}); + }).toThrowError('Input must have properties x and y'); +}); + +test('expect publicKeyIntToUint8ArrayPointPair to throw an error for a non object', () => { + expect(() => { + mapper.publicKeyIntToUint8ArrayPointPair(6); + }).toThrowError('Input must be an object with properties x and y'); +}); + +test('convert a public key x,y where x and y are integers to a pair of Uint8Arrays', () => { + const ecpoint = { + x: 112971204272793929541699765384018665134067875121047561926148644683187420494774n, + y: 13038276010400560657327464707708345466200402936352359974176190171319880557135n + }; + const output = { xOctet : Uint8Array.from([ + 249, 195, 111, 137, 100, 98, 51, + 120, 189, 192, 104, 212, 188, 224, + 126, 209, 124, 143, 164, 134, 249, + 172, 12, 38, 19, 202, 60, 140, + 48, 109, 123, 182 + ] ) , + yOctet : Uint8Array.from([ + 28, 211, 103, 23, 184, 172, 94, 79, + 234, 138, 210, 61, 200, 208, 120, 60, + 35, 24, 238, 74, 215, 168, 13, 182, + 224, 2, 106, 208, 176, 114, 162, 79 + ] ) + }; + + const u8aPoint = mapper.publicKeyIntToUint8ArrayPointPair(ecpoint); + expect(u8aPoint).toEqual(output); +}); + + +test('test a compressed public key in hex to an x,y point as BigInt (with the wrong parity)', () => { + const inputPublicKeyHex = '02f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb6'; + const output = { + x: 112971204272793929541699765384018665134067875121047561926148644683187420494774n, + y: 102753813199955688105369982241699228063885740478937954221357441137547217296816n + }; + const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); + const point = mapper.ECPointDecompress(publicKey_u8a); + expect(point).toEqual(output); +}); + + +test('key decompression (y-coordinate even)', () => { + const inputCompressedPoint = Uint8Array.from([2,57,195,221,116,19,23,41,68,109,193,179,218,103,212,159,192,70,252,191,7,47,204,91,159,165,28,5,185,116,48,127,150]); + const output = { + x: 26127895962184884692520600754586230836934108530588605558459884945533706469270n, + y: 70674290392969052505695590170208788569527910698023358885182794820324123289078n + }; + + const point = mapper.ECPointDecompress( inputCompressedPoint ); + + expect(point).toEqual(output); +}); + +test('key compression (y-coordinate even)', () => { + // inputPublicKeyHex derived from: https://stackoverflow.com/questions/67135136/unable-to-verify-a-raw-uint8array-ecdsa-secp256r1-message-signature-pubkey-usi + + const inputPublicKeyHex = '39c3dd74131729446dc1b3da67d49fc046fcbf072fcc5b9fa51c05b974307f969c403b1635f0449f02bd422751e33121a4434f152f2b2b2a3f675219c5d925f6' + const output = Uint8Array.from([2,57,195,221,116,19,23,41,68,109,193,179,218,103,212,159,192,70,252,191,7,47,204,91,159,165,28,5,185,116,48,127,150]); + + const u8aPoint = mapper.publicKeyHexToUint8ArrayPointPair(inputPublicKeyHex); + const compressedPoint = ECPointCompress(u8aPoint.xOctet, u8aPoint.yOctet); + + expect(compressedPoint).toEqual(output); + +}); + +test('key decompression (y-coordinate odd) key#2', () => { + + const inputCompressedPoint = Uint8Array.from([3,127,35,88,48,221,61,239,167,34,239,26,162,73,214,160,221,187,164,249,144,176,129,117,56,147,63,87,54,64,101,53,66]); + const output = { + x: 57506180088397527878367021711159096752486239922681589595989108987041675556162n, + y: 60351358491784072971514173700673656664870632871947100762396585099496243621173n + }; + + const point = mapper.ECPointDecompress( inputCompressedPoint ) + + expect(point).toEqual(output); +}); + +test('key compression (y-coordinate odd) key#2', () => { + const inputPublicKeyHex = '7f235830dd3defa722ef1aa249d6a0ddbba4f990b0817538933f573640653542856da88d335f1fb25b8bcfbe089528dce09b1f7cb99fdd60f88300f4c2cc6d35' + const output = Uint8Array.from([3,127,35,88,48,221,61,239,167,34,239,26,162,73,214,160,221,187,164,249,144,176,129,117,56,147,63,87,54,64,101,53,66]); + + const u8aPoint = mapper.publicKeyHexToUint8ArrayPointPair(inputPublicKeyHex); + const compressedPoint = ECPointCompress(u8aPoint.xOctet, u8aPoint.yOctet); + + expect(compressedPoint).toEqual(output); +}); + +test('key decompression (y-coordinate odd)', () => { + + const inputCompressedPoint = Uint8Array.from([3,249,195,111,137,100,98,51,120,189,192,104,212,188,224,126,209,124,143,164,134,249,172,12,38,19,202,60,140,48,109,123,182]); + const output = { + x: 112971204272793929541699765384018665134067875121047561926148644683187420494774n, + y: 13038276010400560657327464707708345466200402936352359974176190171319880557135n + }; + + const point = mapper.ECPointDecompress( inputCompressedPoint ) + + expect(point).toEqual(output); +}); + +test('key compression (y-coordinate odd)', () => { + const inputPublicKeyHex = 'f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb61cd36717b8ac5e4fea8ad23dc8d0783c2318ee4ad7a80db6e0026ad0b072a24f' + const output = Uint8Array.from([3,249,195,111,137,100,98,51,120,189,192,104,212,188,224,126,209,124,143,164,134,249,172,12,38,19,202,60,140,48,109,123,182]); + + const u8aPoint = mapper.publicKeyHexToUint8ArrayPointPair(inputPublicKeyHex); + const compressedPoint = ECPointCompress(u8aPoint.xOctet, u8aPoint.yOctet); + + expect(compressedPoint).toEqual(output); +}); + +test('raw public key as hex string to x,y point with x and y as uint8Arrays', () => { + const inputPublicKeyHex = 'f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb61cd36717b8ac5e4fea8ad23dc8d0783c2318ee4ad7a80db6e0026ad0b072a24f' + const output = { xOctet : Uint8Array.from([ + 249, 195, 111, 137, 100, 98, 51, + 120, 189, 192, 104, 212, 188, 224, + 126, 209, 124, 143, 164, 134, 249, + 172, 12, 38, 19, 202, 60, 140, + 48, 109, 123, 182 + ] ) , + yOctet : Uint8Array.from([ + 28, 211, 103, 23, 184, 172, 94, 79, + 234, 138, 210, 61, 200, 208, 120, 60, + 35, 24, 238, 74, 215, 168, 13, 182, + 224, 2, 106, 208, 176, 114, 162, 79 + ] ) + }; + + const u8aPoint = mapper.publicKeyHexToUint8ArrayPointPair(inputPublicKeyHex); + expect(u8aPoint).toEqual(output); +}); + +test('show how to compress a raw public key in hex and return a compressed key in hex', () => { + const inputPublicKeyHex = 'f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb61cd36717b8ac5e4fea8ad23dc8d0783c2318ee4ad7a80db6e0026ad0b072a24f'; + const output = '03f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb6'; + const compresedKey = compresedKeyInHex(inputPublicKeyHex); + expect(compresedKey).toEqual(output); +}); + +test('show how to convert a raw public key in hex and return an uncompressed key in hex', () => { + const inputPublicKeyHex = 'f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb61cd36717b8ac5e4fea8ad23dc8d0783c2318ee4ad7a80db6e0026ad0b072a24f'; + const output = '04f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb61cd36717b8ac5e4fea8ad23dc8d0783c2318ee4ad7a80db6e0026ad0b072a24f'; + const uncompressedKey = '04'+ inputPublicKeyHex; + expect(uncompressedKey).toEqual(output); +}); + +/* + * tests for functions declared within the test file + * + */ + + +test('test a null coordinates in ECPointCompress', () => { + const x = null; + const y = null; + expect(() => { + ECPointCompress(x,y); + }).toThrowError('input cannot be null or undefined.'); +}); + +test('test a undefined coordinates in ECPointCompress', () => { + const x = undefined; + const y = undefined; + expect(() => { + ECPointCompress(x,y); + }).toThrowError('input cannot be null or undefined.'); +}); + +test('test null in pubKeyHexToUint8Array', () => { + const inputPublicKeyHex = null; + expect(() => { + pubKeyHexToUint8Array(inputPublicKeyHex); + }).toThrowError('input cannot be null or undefined.'); +}); + +test('test undefined in pubKeyHexToUint8Array', () => { + const inputPublicKeyHex = undefined; + expect(() => { + pubKeyHexToUint8Array(inputPublicKeyHex); + }).toThrowError('input cannot be null or undefined.'); +}); + +test('test an empty string in pubKeyHexToUint8Array', () => { + const inputPublicKeyHex = '' + const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); + expect(publicKey_u8a).toBeDefined(); + expect(publicKey_u8a).not.toBeNull(); + // removed because jest gives::: Received: serializes to the same string + // expect(publicKey_u8a).toEqual([]) +}); + +test('test compresedKeyInHex with an empty string', () => { + const inputPublicKeyHex = ''; + const compressedKey = compresedKeyInHex(inputPublicKeyHex); + expect(compressedKey).toBeDefined(); + expect(compressedKey).not.toBeNull(); +}); + +test('test compresedKeyInHex with null', () => { + const inputPublicKeyHex = null; + expect(() => { + compresedKeyInHex(inputPublicKeyHex); + }).toThrowError('input cannot be null or undefined.'); +}); + +test('test compresedKeyInHex with undefined', () => { + const inputPublicKeyHex = undefined; + expect(() => { + compresedKeyInHex(inputPublicKeyHex); + }).toThrowError('input cannot be null or undefined.'); +}); + +//**** end of tests for functions withing the test file + +// write a separate test for this function... +// source: https://stackoverflow.com/questions/17171542/algorithm-for-elliptic-curve-point-compression +function ECPointCompress( x: Uint8Array, y: Uint8Array ) +{ + + if(x == null || y == null) { + throw new TypeError('input cannot be null or undefined.'); + } + + const out = new Uint8Array( x.length + 1 ); + + out[0] = 2 + ( y[ y.length-1 ] & 1 ); + out.set( x, 1 ); + + return out; +} + +function pubKeyHexToUint8Array(publicKeyHex: string) { + if(publicKeyHex == null) { + throw new TypeError('input cannot be null or undefined.'); + } + if(publicKeyHex.length % 2 == 0) { + return u8a.fromString(publicKeyHex,'base16'); + } else { + return u8a.fromString(('0'+publicKeyHex),'base16'); + } +} + +function compresedKeyInHex(publicKeyHex: string) { + if(publicKeyHex == null) { + throw new TypeError('input cannot be null or undefined.'); + } + const xHex = publicKeyHex.slice(0,publicKeyHex.length/2); + const yHex = publicKeyHex.slice(publicKeyHex.length/2,publicKeyHex.length); + + const xOctet = u8a.fromString(xHex,'base16') + const yOctet = u8a.fromString(yHex,'base16'); + + const compressedPoint = ECPointCompress( xOctet , yOctet ); + const compressedPointHex = u8a.toString(compressedPoint,'base16'); + return compressedPointHex; +} diff --git a/packages/key-did-resolver/src/index.ts b/packages/key-did-resolver/src/index.ts index 71a86f7703..d93a23dd22 100644 --- a/packages/key-did-resolver/src/index.ts +++ b/packages/key-did-resolver/src/index.ts @@ -10,6 +10,7 @@ import type { import * as secp256k1 from './secp256k1' import * as ed25519 from './ed25519' +import * as secp256r1 from './secp256r1' const DID_LD_JSON = 'application/did+ld+json' const DID_JSON = 'application/did+json' @@ -17,6 +18,7 @@ const DID_JSON = 'application/did+json' const prefixToDriverMap: any = { 0xE7: secp256k1, 0xED: ed25519, + 0x1200: secp256r1, } export default { diff --git a/packages/key-did-resolver/src/secp256r1.ts b/packages/key-did-resolver/src/secp256r1.ts new file mode 100644 index 0000000000..be009c81fd --- /dev/null +++ b/packages/key-did-resolver/src/secp256r1.ts @@ -0,0 +1,272 @@ +// Brent Shambaugh . 2021. + +import * as u8a from 'uint8arrays' +import multibase from'multibase' +import * as bigintModArith from 'bigint-mod-arith' + +/** + * x,y point as a BigInt (requires at least ES2020) + * For BigInt see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt + */ +interface BigIntPoint { + x: BigInt, + y : BigInt +} + +/** + * xm,ym point with components expresse with base64url utilizing multiformats + * + * base64url is expressed in the Multibase Table: https://github.com/multiformats/multibase/blob/master/multibase.csv + */ +interface base64urlPoint { + xm: string, + ym: string +} + +/** + * Elliptic curve point with coordinates expressed as byte arrays (Uint8Array) + */ +interface octetPoint { + xOctet: Uint8Array, + yOctet: Uint8Array +} + +/** + * Constructs the document based on the method key + */ +export function keyToDidDoc (pubKeyBytes: Uint8Array, fingerprint: string): any { + const did = `did:key:${fingerprint}` + const keyId = `${did}#${fingerprint}` + const key = pubKeyBytesToXY(pubKeyBytes); + return { + id: did, + verificationMethod: [{ + id: keyId, + type: 'JsonWebKey2020', + controller: did, + publicKeyJwk: { + kty: "EC", + crv: "P-256", + x: key.xm, + y: key.ym, + }, + }], + authentication: [keyId], + assertionMethod: [keyId], + capabilityDelegation: [keyId], + capabilityInvocation: [keyId], + } + } + +/** + * Converts a byte array into a Hex String. + * + * @param pubKeyBytes - public key + * @returns hex string + * @throws TypeError: input cannot be null or undefined. + */ +export function pubKeyBytesToHex(pubKeyBytes: Uint8Array) : string { + if(!testUint8Array(pubKeyBytes)) { + throw new TypeError('input must be a Uint8Array'); + } + const bbf = u8a.toString(pubKeyBytes,'base16') + return bbf; +} + +/** + * Decompress a compressed public key in SEC format. + * See section 2.3.3 in SEC 1 v2 : https://www.secg.org/sec1-v2.pdf. + * + * Code based on: https://stackoverflow.com/questions/17171542/algorithm-for-elliptic-curve-point-compression/30431547#30431547 + * + * @param - 33 byte compressed public key. 1st byte: 0x02 for even or 0x03 for odd. Following 32 bytes: x coordinate expressed as big-endian. + * @throws TypeError: input cannot be null or undefined. + */ + export function ECPointDecompress( comp : Uint8Array ) : BigIntPoint { + if(!testUint8Array(comp)) { + throw new TypeError('input must be a Uint8Array'); + } + // two, prime, b, and pIdent are constants for the P-256 curve + const two = BigInt(2); + const prime = (two ** 256n) - (two ** 224n) + (two ** 192n) + (two ** 96n) - 1n; + const b = 41058363725152142129326129780047268409114441015993725554835256314039467401291n; + const pIdent = (prime + 1n) / 4n; + + const signY = BigInt(comp[0] - 2); + const x = comp.subarray(1); + const xBig = BigInt(u8a.toString(x,'base10')); + + const a = xBig**3n - xBig*3n + b; + let yBig = bigintModArith.modPow(a,pIdent,prime); + + // "// If the parity doesn't match it's the *other* root" + if( yBig % 2n !== signY) + { + // y = prime - y + yBig = prime - yBig; + } + + return { + x: xBig, + y: yBig + }; + +} + +/** + * + * @param publicKeyHex - public key as hex string. + * @returns + * @throws TypeError: input cannot be null or undefined. + */ +export function publicKeyToXY(publicKeyHex: string) : base64urlPoint { + if(!testHexString(publicKeyHex)) { + throw new TypeError('input must be string with characters 0-9,A-F,a-f'); + } + const u8aOctetPoint = publicKeyHexToUint8ArrayPointPair(publicKeyHex); + const xm = u8a.toString(multibase.encode('base64url',u8aOctetPoint.xOctet)); + const ym = u8a.toString(multibase.encode('base64url',u8aOctetPoint.yOctet)); + return { xm, ym }; +} + +/** + * + * @param publicKeyHex - public key as hex string. + * @returns - point with Uint8Array bytes using base16 + * @throws TypeError: input cannot be null or undefined. + */ +export function publicKeyHexToUint8ArrayPointPair(publicKeyHex: string) : octetPoint { + if(!testHexString(publicKeyHex)) { + throw new TypeError('input must be string with characters 0-9,A-F,a-f'); + } + const xHex = publicKeyHex.slice(0,publicKeyHex.length/2); + const yHex = publicKeyHex.slice(publicKeyHex.length/2,publicKeyHex.length); + const xOctet = u8a.fromString(xHex,'base16'); + const yOctet = u8a.fromString(yHex,'base16'); + return { xOctet, yOctet }; +} + +/** + * Tests to see if the argument is a Hex String. + * @param str + * @returns + */ +export function testHexString(str : string) : boolean { + const regex = new RegExp(/^[A-Fa-f0-9]+/i); + if(regex.test(str)) { + if(str.length == regex.exec(str)[0].length) { + return true; + } + } + return false; +} + +/** + * Test to see if the argument is the Uint8Array + * @param param + * @returns + */ +export function testUint8Array(param: Uint8Array) : boolean { + if(param == null) { + return false; + } + if(param.constructor === Uint8Array) { + return true; + } else { + return false; + } +} + + +/** + * + * @param ecpoint - Public key. + * @returns Uint8Array with bytes as base16 + * @throws TypeError: input cannot be null or undefined. + * @throws Error: Input coordinates must be BigInt + * @throws Error: Input must have properties x and y + * @throws TypeError: Input must be an object with properties x and y +*/ +export function publicKeyIntToXY(ecpoint: BigIntPoint): base64urlPoint { + if(ecpoint == null) { throw new TypeError('input cannot be null or undefined.'); } + + if(typeof ecpoint !== "object") { throw new TypeError("Input must be an object with properties x and y"); } + + if(!Object.prototype.hasOwnProperty.call(ecpoint, "x") || !Object.prototype.hasOwnProperty.call(ecpoint, "y")) { throw new Error("Input must have properties x and y"); } + + if(typeof ecpoint.x !== "bigint" && typeof ecpoint.y !== "bigint") { throw new Error("Input coordinates must be BigInt"); } + + const u8aOctetPoint = publicKeyIntToUint8ArrayPointPair(ecpoint); + const xm = u8a.toString(multibase.encode('base64url',u8aOctetPoint.xOctet)); + const ym = u8a.toString(multibase.encode('base64url',u8aOctetPoint.yOctet)); + return { xm, ym }; +} + +/** + * + * @param ecpoint - Public key. + * @returns Uint8Array with bytes as base10 + * @throws TypeError: input cannot be null or undefined. + * @throws Error: Input coordinates must be BigInt + * @throws Error: Input must have properties x and y + * @throws TypeError: Input must be an object with properties x and y + */ +export function publicKeyIntToUint8ArrayPointPair(ecpoint: BigIntPoint) : octetPoint { + if(ecpoint == null) { throw new TypeError('input cannot be null or undefined.'); } + + if(typeof ecpoint !== "object") { throw new TypeError("Input must be an object with properties x and y"); } + + if(!Object.prototype.hasOwnProperty.call(ecpoint, "x") || !Object.prototype.hasOwnProperty.call(ecpoint, "y")) { throw new Error("Input must have properties x and y"); } + + if(typeof ecpoint.x !== "bigint" && typeof ecpoint.y !== "bigint") { throw new Error("Input coordinates must be BigInt"); } + + const xHex = (ecpoint.x).toString(); + const yHex = (ecpoint.y).toString(); + const xOctet = u8a.fromString(xHex,'base10'); + const yOctet = u8a.fromString(yHex,'base10'); + return { xOctet, yOctet }; +} + +/** + * + * @param pubKeyBytes - public key as uncompressed byte array with no prefix (raw key), + * uncompressed with 0x04 prefix, or compressed with 0x02 prefix if even and 0x03 prefix if odd. + * @returns point x,y with coordinates as multibase encoded base64urls + * + * See the the did:key specification: https://w3c-ccg.github.io/did-method-key/#p-256. + * At present only raw p-256 keys are covered in the specification. + * @throws TypeError: input cannot be null or undefined. + * @throws Error: Unexpected pubKeyBytes + * @internal + */ +export function pubKeyBytesToXY(pubKeyBytes: Uint8Array) : base64urlPoint { + if(!testUint8Array(pubKeyBytes)) { + throw new TypeError('input must be a Uint8Array'); + } + const publicKeyHex = pubKeyBytesToHex(pubKeyBytes); + const bytesCount = publicKeyHex.length / 2; + + // raw p-256 key + if(bytesCount == 64) { + return publicKeyToXY(publicKeyHex); + } + + // uncompressed p-256 key, SEC format + if(bytesCount == 65) { + if(publicKeyHex.slice(0,2) == '04') { + const publicKey = publicKeyHex.slice(2); + return publicKeyToXY(publicKey); + } + } + + // compressed p-256 key, SEC format + if(bytesCount == 33) { + if(publicKeyHex.slice(0,2) == '03' || publicKeyHex.slice(0,2) == '02') { + const publicKey = u8a.fromString(publicKeyHex,'base16') + const point = ECPointDecompress(publicKey); + return publicKeyIntToXY(point); + } + } + + throw new Error('Unexpected pubKeyBytes'); +} diff --git a/tsconfig.json b/tsconfig.json index eba0fbdbf9..d3bf319d9f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "module": "commonjs", "lib": ["es6", "dom", "esnext"], - "target": "ES2018", + "target": "ES2020", "declaration": true, "declarationMap": true, "skipLibCheck": true, From 259e1a12c37a1b3ed5fa39aae75974e102f020d5 Mon Sep 17 00:00:00 2001 From: Brent Shambaugh Date: Wed, 1 Dec 2021 19:41:01 -0600 Subject: [PATCH 02/38] commit changes pulled from private develop branch into feat/secp256r1 branch --- packages/key-did-resolver/README.md | 300 ++++++++++ .../__snapshots__/index.test.ts.snap | 174 +++++- .../__snapshots__/secp256r1.test.ts.snap | 156 +++++- .../__snapshots__/secp384r1.test.ts.snap | 249 +++++++++ .../__snapshots__/secp521r1.test.ts.snap | 94 ++++ .../src/__tests__/index.test.ts | 84 +++ .../__tests__/nist_weierstrass_common.test.ts | 458 ++++++++++++++++ .../src/__tests__/secp256r1.test.ts | 513 +++--------------- .../src/__tests__/secp384r1.test.ts | 292 ++++++++++ .../src/__tests__/secp521r1.test.ts | 176 ++++++ packages/key-did-resolver/src/index.ts | 34 +- .../src/nist_weierstrass_common.ts | 162 ++++++ packages/key-did-resolver/src/secp256r1.ts | 152 +----- packages/key-did-resolver/src/secp384r1.ts | 136 +++++ packages/key-did-resolver/src/secp521r1.ts | 122 +++++ 15 files changed, 2468 insertions(+), 634 deletions(-) create mode 100644 packages/key-did-resolver/src/__tests__/__snapshots__/secp384r1.test.ts.snap create mode 100644 packages/key-did-resolver/src/__tests__/__snapshots__/secp521r1.test.ts.snap create mode 100644 packages/key-did-resolver/src/__tests__/nist_weierstrass_common.test.ts create mode 100644 packages/key-did-resolver/src/__tests__/secp384r1.test.ts create mode 100644 packages/key-did-resolver/src/__tests__/secp521r1.test.ts create mode 100644 packages/key-did-resolver/src/nist_weierstrass_common.ts create mode 100644 packages/key-did-resolver/src/secp384r1.ts create mode 100644 packages/key-did-resolver/src/secp521r1.ts diff --git a/packages/key-did-resolver/README.md b/packages/key-did-resolver/README.md index 0dbece95f8..410d1c1643 100644 --- a/packages/key-did-resolver/README.md +++ b/packages/key-did-resolver/README.md @@ -6,6 +6,306 @@ ``` $ npm install key-did-resolver ``` +### Usage + +This code supports compressed did:keys in concordance with https://github.com/w3c-ccg/did-method-key test-vectors. + +The did:key id is the multicodec name + the compressed public key expressed as a Uint8Array (byte array) then encoded with base58btc and expressed as a string. + +Example code for creating a did:key for Ed25519 is here: +https://github.com/ceramicnetwork/key-did-provider-ed25519 + +Example code for creating a did:key for Secp256k1 is here: +https://github.com/ceramicnetwork/key-did-provider-secp256k1 + +Example code for creating a did:key for P-256, P-384, and P-521 is here: +https://github.com/bshambaugh/did-key-creator + +Compressed keys are the X coordinate of the public key with a prefix that depends on the sign of the Y curve coordinate. The prefix is '02' if even and '03' if odd. +More information is here: https://tools.ietf.org/id/draft-jivsov-ecc-compact-05.html . + +## Code +``` +// Usage from cloned GitHub Repository: +// import * as keyDIDResolver from '../js-ceramic/packages/key-did-resolver/lib/index.js'; + +import keyDIDResolver from 'key-did-resolver' + +const resolverRegistry = keyDIDResolver.getResolver(); + +const resolve = resolverRegistry.key; + +let parsedDided25519 = { + id: "z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8", + did: 'did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8', + method: "key", + didUrl: 'did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8/some/path', + path: '/some/path' +} + +let doced25519 = await resolve('did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8', parsedDided25519, {}, { accept: 'application/did+ld+json' }) + +console.log(); +console.log('did document for ed25519:'); +console.log(doced25519); +console.log(); + +console.log('did document metatdata:'); +console.log(doced25519.didDocument.verificationMethod); + +let parsedDid256k1 = { + id: "zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz", + did: 'did:key:zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz', + method: "key", + didUrl: 'did:key:zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz/some/path', + path: '/some/path' +} + +let doc256k1 = await resolve('did:key:zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz', parsedDid256k1, {}, { accept: 'application/did+ld+json' }) + +console.log(); +console.log('did document for secp256k1:'); +console.log(doc256k1); +console.log(); + +console.log('did document metatdata:'); +console.log(doc256k1.didDocument.verificationMethod); + +let parsedDid256 = { + id: "zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu", + did: 'did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu', + method: "key", + didUrl: 'did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu/some/path', + path: '/some/path' +} + +let doc256 = await resolve('did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu', parsedDid256, {}, { accept: 'application/did+ld+json' }) + +console.log(); +console.log('did document for P-256:'); +console.log(doc256); +console.log(); + +console.log('did document metatdata:'); +console.log(doc256.didDocument.verificationMethod); + +let parsedDid384 = { + id: "z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54", + did: 'did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54', + method: "key", + didUrl: 'did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54/some/path', + path: '/some/path' +} + +let doc384 = await resolve('did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54', parsedDid384, {}, { accept: 'application/did+ld+json' }) + +console.log(); +console.log('did document for P-384:'); +console.log(doc384); +console.log(); + +console.log('did document metatdata:'); +console.log(doc384.didDocument.verificationMethod); + +let parsedDid521 = { + id: "z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t", + did: 'did:key:z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t', + method: "key", + didUrl: 'did:key:z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t/some/path', + path: '/some/path' +} + +let doc521 = await resolve('did:key:z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t', parsedDid521, {}, { accept: 'application/did+ld+json' }) + +console.log(); +console.log('did document for P-521:'); +console.log(doc521) +console.log(); + +console.log('did document metadata:'); +console.log(doc521.didDocument.verificationMethod); + +``` + +## Output +``` + +did document for ed25519: +{ + didResolutionMetadata: { contentType: 'application/did+ld+json' }, + didDocument: { + id: 'did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8', + verificationMethod: [ [Object] ], + authentication: [ + 'did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8#z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8' + ], + assertionMethod: [ + 'did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8#z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8' + ], + capabilityDelegation: [ + 'did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8#z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8' + ], + capabilityInvocation: [ + 'did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8#z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8' + ], + keyAgreement: [ [Object] ], + '@context': 'https://w3id.org/did/v1' + }, + didDocumentMetadata: {} +} + +did document for secp256k1: +{ + didResolutionMetadata: { contentType: 'application/did+ld+json' }, + didDocument: { + id: 'did:key:zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz', + verificationMethod: [ [Object] ], + authentication: [ + 'did:key:zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz#zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz' + ], + assertionMethod: [ + 'did:key:zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz#zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz' + ], + capabilityDelegation: [ + 'did:key:zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz#zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz' + ], + capabilityInvocation: [ + 'did:key:zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz#zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz' + ], + '@context': 'https://w3id.org/did/v1' + }, + didDocumentMetadata: {} +} + +did document metatdata: +[ + { + id: 'did:key:zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz#zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz', + type: 'Secp256k1VerificationKey2018', + controller: 'did:key:zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz', + publicKeyBase58: 'qjdSRUCiVtAjwdYVTxHQXd9FnMPRaYCtKpkchofTw66G' + } +] + +did document for P-256: +{ + didResolutionMetadata: { contentType: 'application/did+ld+json' }, + didDocument: { + id: 'did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu', + verificationMethod: [ [Object] ], + authentication: [ + 'did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu#zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu' + ], + assertionMethod: [ + 'did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu#zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu' + ], + capabilityDelegation: [ + 'did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu#zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu' + ], + capabilityInvocation: [ + 'did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu#zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu' + ], + '@context': 'https://w3id.org/did/v1' + }, + didDocumentMetadata: {} +} + +did document metadata: +[ + { + id: 'did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu#zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu', + type: 'JsonWebKey2020', + controller: 'did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu', + publicKeyJwk: { + kty: 'EC', + crv: 'P-256', + x: 'OcPddBMXKURtwbPaZ9SfwEb8vwcvzFufpRwFuXQwf5Y', + y: 'nEA7FjXwRJ8CvUInUeMxIaRDTxUvKysqP2dSGcXZJfY' + } + } +] + +did document for P-384: +{ + didResolutionMetadata: { contentType: 'application/did+ld+json' }, + didDocument: { + id: 'did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54', + verificationMethod: [ [Object] ], + authentication: [ + 'did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54#z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54' + ], + assertionMethod: [ + 'did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54#z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54' + ], + capabilityDelegation: [ + 'did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54#z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54' + ], + capabilityInvocation: [ + 'did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54#z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54' + ], + '@context': 'https://w3id.org/did/v1' + }, + didDocumentMetadata: {} +} + +did document metadata: +[ + { + id: 'did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54#z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54', + type: 'JsonWebKey2020', + controller: 'did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54', + publicKeyJwk: { + kty: 'EC', + crv: 'P-384', + x: 'CA-iNoHDg1lL8pvX3d1uvExzVfCz7Rn6tW781Ub8K5MrDf2IMPyL0RTDiaLHC1JT', + y: 'Kpnrn8DkXUD3ge4mFxi-DKr0DYO2KuJdwNBrhzLRtfMa3WFMZBiPKUPfJj8dYNl_' + } + } +] + +did document for P-521: +{ + didResolutionMetadata: { contentType: 'application/did+ld+json' }, + didDocument: { + id: 'did:key:z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t', + verificationMethod: [ [Object] ], + authentication: [ + 'did:key:z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t#z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t' + ], + assertionMethod: [ + 'did:key:z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t#z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t' + ], + capabilityDelegation: [ + 'did:key:z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t#z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t' + ], + capabilityInvocation: [ + 'did:key:z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t#z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t' + ], + '@context': 'https://w3id.org/did/v1' + }, + didDocumentMetadata: {} +} + +did document metadata: +[ + { + id: 'did:key:z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t#z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t', + type: 'JsonWebKey2020', + controller: 'did:key:z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t', + publicKeyJwk: { + kty: 'EC', + crv: 'P-521', + x: 'ATkofCC8_KAAJ3XSRayyPk8WqF9qahhoQVjbHtzbe5MSaaFiMKBZr-CurF9IcpJD-YYEukPmarSKFpXLtwAdiONT', + y: 'AWuYkJ7iaFhfz_dzFemaBnuq1WFnoZeIha7KpE9benPTX9FQhAoyHY-2qO4IyqGe1XGGtx8eJXvp57xMtUXm2rAH' + } + } +] + +``` + +## Comments +During development there was not yet consensus on using all compressed keys. Support for uncompressed keys with the '04' prefix and +raw keys (just the x,y bytes with no prefix) was kept for the P-256 and P-384 curves. ## Contributing We are happy to accept small and large contributions. Make sure to check out the [Ceramic specifications](https://github.com/ceramicnetwork/specs) for details of how the protocol works. diff --git a/packages/key-did-resolver/src/__tests__/__snapshots__/index.test.ts.snap b/packages/key-did-resolver/src/__tests__/__snapshots__/index.test.ts.snap index 8f1a0ffc01..03fa0771bf 100644 --- a/packages/key-did-resolver/src/__tests__/__snapshots__/index.test.ts.snap +++ b/packages/key-did-resolver/src/__tests__/__snapshots__/index.test.ts.snap @@ -170,8 +170,8 @@ Object { "publicKeyJwk": Object { "crv": "P-256", "kty": "EC", - "x": "u-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y", - "y": "uHNNnF7isXk_qitI9yNB4PCMY7krXqA224AJq0LByok8", + "x": "-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y", + "y": "HNNnF7isXk_qitI9yNB4PCMY7krXqA224AJq0LByok8", }, "type": "JsonWebKey2020", }, @@ -207,8 +207,8 @@ Object { "publicKeyJwk": Object { "crv": "P-256", "kty": "EC", - "x": "u-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y", - "y": "uHNNnF7isXk_qitI9yNB4PCMY7krXqA224AJq0LByok8", + "x": "-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y", + "y": "HNNnF7isXk_qitI9yNB4PCMY7krXqA224AJq0LByok8", }, "type": "JsonWebKey2020", }, @@ -245,8 +245,8 @@ Object { "publicKeyJwk": Object { "crv": "P-256", "kty": "EC", - "x": "uOcPddBMXKURtwbPaZ9SfwEb8vwcvzFufpRwFuXQwf5Y", - "y": "unEA7FjXwRJ8CvUInUeMxIaRDTxUvKysqP2dSGcXZJfY", + "x": "OcPddBMXKURtwbPaZ9SfwEb8vwcvzFufpRwFuXQwf5Y", + "y": "nEA7FjXwRJ8CvUInUeMxIaRDTxUvKysqP2dSGcXZJfY", }, "type": "JsonWebKey2020", }, @@ -282,8 +282,8 @@ Object { "publicKeyJwk": Object { "crv": "P-256", "kty": "EC", - "x": "uOcPddBMXKURtwbPaZ9SfwEb8vwcvzFufpRwFuXQwf5Y", - "y": "unEA7FjXwRJ8CvUInUeMxIaRDTxUvKysqP2dSGcXZJfY", + "x": "OcPddBMXKURtwbPaZ9SfwEb8vwcvzFufpRwFuXQwf5Y", + "y": "nEA7FjXwRJ8CvUInUeMxIaRDTxUvKysqP2dSGcXZJfY", }, "type": "JsonWebKey2020", }, @@ -320,8 +320,8 @@ Object { "publicKeyJwk": Object { "crv": "P-256", "kty": "EC", - "x": "u-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y", - "y": "uHNNnF7isXk_qitI9yNB4PCMY7krXqA224AJq0LByok8", + "x": "-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y", + "y": "HNNnF7isXk_qitI9yNB4PCMY7krXqA224AJq0LByok8", }, "type": "JsonWebKey2020", }, @@ -357,8 +357,158 @@ Object { "publicKeyJwk": Object { "crv": "P-256", "kty": "EC", - "x": "u-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y", - "y": "uHNNnF7isXk_qitI9yNB4PCMY7krXqA224AJq0LByok8", + "x": "-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y", + "y": "HNNnF7isXk_qitI9yNB4PCMY7krXqA224AJq0LByok8", + }, + "type": "JsonWebKey2020", + }, + ], + }, + "didDocumentMetadata": Object {}, + "didResolutionMetadata": Object { + "contentType": "application/did+json", + }, +} +`; + +exports[`Index mapper successfully resolves the document from did 11`] = ` +Object { + "didDocument": Object { + "@context": "https://w3id.org/did/v1", + "assertionMethod": Array [ + "did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY#z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", + ], + "authentication": Array [ + "did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY#z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", + ], + "capabilityDelegation": Array [ + "did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY#z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", + ], + "capabilityInvocation": Array [ + "did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY#z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", + ], + "id": "did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", + "verificationMethod": Array [ + Object { + "controller": "did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", + "id": "did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY#z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", + "publicKeyJwk": Object { + "crv": "P-256", + "kty": "EC", + "x": "-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y", + "y": "HNNnF7isXk_qitI9yNB4PCMY7krXqA224AJq0LByok8", + }, + "type": "JsonWebKey2020", + }, + ], + }, + "didDocumentMetadata": Object {}, + "didResolutionMetadata": Object { + "contentType": "application/did+ld+json", + }, +} +`; + +exports[`Index mapper successfully resolves the document from did 12`] = ` +Object { + "didDocument": Object { + "assertionMethod": Array [ + "did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY#z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", + ], + "authentication": Array [ + "did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY#z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", + ], + "capabilityDelegation": Array [ + "did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY#z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", + ], + "capabilityInvocation": Array [ + "did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY#z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", + ], + "id": "did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", + "verificationMethod": Array [ + Object { + "controller": "did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", + "id": "did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY#z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", + "publicKeyJwk": Object { + "crv": "P-256", + "kty": "EC", + "x": "-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y", + "y": "HNNnF7isXk_qitI9yNB4PCMY7krXqA224AJq0LByok8", + }, + "type": "JsonWebKey2020", + }, + ], + }, + "didDocumentMetadata": Object {}, + "didResolutionMetadata": Object { + "contentType": "application/did+json", + }, +} +`; + +exports[`Index mapper successfully resolves the document from did 13`] = ` +Object { + "didDocument": Object { + "@context": "https://w3id.org/did/v1", + "assertionMethod": Array [ + "did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54#z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54", + ], + "authentication": Array [ + "did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54#z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54", + ], + "capabilityDelegation": Array [ + "did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54#z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54", + ], + "capabilityInvocation": Array [ + "did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54#z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54", + ], + "id": "did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54", + "verificationMethod": Array [ + Object { + "controller": "did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54", + "id": "did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54#z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54", + "publicKeyJwk": Object { + "crv": "P-384", + "kty": "EC", + "x": "CA-iNoHDg1lL8pvX3d1uvExzVfCz7Rn6tW781Ub8K5MrDf2IMPyL0RTDiaLHC1JT", + "y": "Kpnrn8DkXUD3ge4mFxi-DKr0DYO2KuJdwNBrhzLRtfMa3WFMZBiPKUPfJj8dYNl_", + }, + "type": "JsonWebKey2020", + }, + ], + }, + "didDocumentMetadata": Object {}, + "didResolutionMetadata": Object { + "contentType": "application/did+ld+json", + }, +} +`; + +exports[`Index mapper successfully resolves the document from did 14`] = ` +Object { + "didDocument": Object { + "assertionMethod": Array [ + "did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54#z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54", + ], + "authentication": Array [ + "did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54#z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54", + ], + "capabilityDelegation": Array [ + "did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54#z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54", + ], + "capabilityInvocation": Array [ + "did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54#z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54", + ], + "id": "did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54", + "verificationMethod": Array [ + Object { + "controller": "did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54", + "id": "did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54#z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54", + "publicKeyJwk": Object { + "crv": "P-384", + "kty": "EC", + "x": "CA-iNoHDg1lL8pvX3d1uvExzVfCz7Rn6tW781Ub8K5MrDf2IMPyL0RTDiaLHC1JT", + "y": "Kpnrn8DkXUD3ge4mFxi-DKr0DYO2KuJdwNBrhzLRtfMa3WFMZBiPKUPfJj8dYNl_", }, "type": "JsonWebKey2020", }, diff --git a/packages/key-did-resolver/src/__tests__/__snapshots__/secp256r1.test.ts.snap b/packages/key-did-resolver/src/__tests__/__snapshots__/secp256r1.test.ts.snap index c4ba23da94..b405f88337 100644 --- a/packages/key-did-resolver/src/__tests__/__snapshots__/secp256r1.test.ts.snap +++ b/packages/key-did-resolver/src/__tests__/__snapshots__/secp256r1.test.ts.snap @@ -1,29 +1,29 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Secp256r1 mapper successfully resolves the document from did 1`] = ` +exports[`Secp256r1 mapper successfully resolves the document from did:key from compressed public key #2 1`] = ` Object { "assertionMethod": Array [ - "did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ#zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ", + "did:key:zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv#zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv", ], "authentication": Array [ - "did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ#zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ", + "did:key:zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv#zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv", ], "capabilityDelegation": Array [ - "did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ#zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ", + "did:key:zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv#zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv", ], "capabilityInvocation": Array [ - "did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ#zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ", + "did:key:zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv#zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv", ], - "id": "did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ", + "id": "did:key:zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv", "verificationMethod": Array [ Object { - "controller": "did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ", - "id": "did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ#zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ", + "controller": "did:key:zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv", + "id": "did:key:zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv#zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv", "publicKeyJwk": Object { "crv": "P-256", "kty": "EC", - "x": "u-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y", - "y": "uHNNnF7isXk_qitI9yNB4PCMY7krXqA224AJq0LByok8", + "x": "igrFmi0whuihKnj9R3Om1SoMph72wUGeFaBbzG2vzns", + "y": "efsX5b10x8yjyrj4ny3pGfLcY7Xby1KzgqOdqnsrJIM", }, "type": "JsonWebKey2020", }, @@ -31,7 +31,38 @@ Object { } `; -exports[`Secp256r1 mapper successfully resolves the document from did 2`] = ` +exports[`Secp256r1 mapper successfully resolves the document from did:key from compressed public key #3 1`] = ` +Object { + "assertionMethod": Array [ + "did:key:zDnaerDaTF5BXEavCrfRZEk316dpbLsfPDZ3WJ5hRTPFU2169#zDnaerDaTF5BXEavCrfRZEk316dpbLsfPDZ3WJ5hRTPFU2169", + ], + "authentication": Array [ + "did:key:zDnaerDaTF5BXEavCrfRZEk316dpbLsfPDZ3WJ5hRTPFU2169#zDnaerDaTF5BXEavCrfRZEk316dpbLsfPDZ3WJ5hRTPFU2169", + ], + "capabilityDelegation": Array [ + "did:key:zDnaerDaTF5BXEavCrfRZEk316dpbLsfPDZ3WJ5hRTPFU2169#zDnaerDaTF5BXEavCrfRZEk316dpbLsfPDZ3WJ5hRTPFU2169", + ], + "capabilityInvocation": Array [ + "did:key:zDnaerDaTF5BXEavCrfRZEk316dpbLsfPDZ3WJ5hRTPFU2169#zDnaerDaTF5BXEavCrfRZEk316dpbLsfPDZ3WJ5hRTPFU2169", + ], + "id": "did:key:zDnaerDaTF5BXEavCrfRZEk316dpbLsfPDZ3WJ5hRTPFU2169", + "verificationMethod": Array [ + Object { + "controller": "did:key:zDnaerDaTF5BXEavCrfRZEk316dpbLsfPDZ3WJ5hRTPFU2169", + "id": "did:key:zDnaerDaTF5BXEavCrfRZEk316dpbLsfPDZ3WJ5hRTPFU2169#zDnaerDaTF5BXEavCrfRZEk316dpbLsfPDZ3WJ5hRTPFU2169", + "publicKeyJwk": Object { + "crv": "P-256", + "kty": "EC", + "x": "fyNYMN0976ci7xqiSdag3buk-ZCwgXU4kz9XNkBlNUI", + "y": "hW2ojTNfH7Jbi8--CJUo3OCbH3y5n91g-IMA9MLMbTU", + }, + "type": "JsonWebKey2020", + }, + ], +} +`; + +exports[`Secp256r1 mapper successfully resolves the document from did:key from compressed public key 1`] = ` Object { "assertionMethod": Array [ "did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu#zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu", @@ -53,8 +84,101 @@ Object { "publicKeyJwk": Object { "crv": "P-256", "kty": "EC", - "x": "uOcPddBMXKURtwbPaZ9SfwEb8vwcvzFufpRwFuXQwf5Y", - "y": "unEA7FjXwRJ8CvUInUeMxIaRDTxUvKysqP2dSGcXZJfY", + "x": "OcPddBMXKURtwbPaZ9SfwEb8vwcvzFufpRwFuXQwf5Y", + "y": "nEA7FjXwRJ8CvUInUeMxIaRDTxUvKysqP2dSGcXZJfY", + }, + "type": "JsonWebKey2020", + }, + ], +} +`; + +exports[`Secp256r1 mapper successfully resolves the document from did:key from raw public key #2 1`] = ` +Object { + "assertionMethod": Array [ + "did:key:zrusAFgBbf84b8mBz8Cmy8UoFWKV52EaeRnK86vnLo4Z5QoRypE6hXVPN2urevZMAMtcTaCDFLWBaE1Q3jmdb1FHgve#zrusAFgBbf84b8mBz8Cmy8UoFWKV52EaeRnK86vnLo4Z5QoRypE6hXVPN2urevZMAMtcTaCDFLWBaE1Q3jmdb1FHgve", + ], + "authentication": Array [ + "did:key:zrusAFgBbf84b8mBz8Cmy8UoFWKV52EaeRnK86vnLo4Z5QoRypE6hXVPN2urevZMAMtcTaCDFLWBaE1Q3jmdb1FHgve#zrusAFgBbf84b8mBz8Cmy8UoFWKV52EaeRnK86vnLo4Z5QoRypE6hXVPN2urevZMAMtcTaCDFLWBaE1Q3jmdb1FHgve", + ], + "capabilityDelegation": Array [ + "did:key:zrusAFgBbf84b8mBz8Cmy8UoFWKV52EaeRnK86vnLo4Z5QoRypE6hXVPN2urevZMAMtcTaCDFLWBaE1Q3jmdb1FHgve#zrusAFgBbf84b8mBz8Cmy8UoFWKV52EaeRnK86vnLo4Z5QoRypE6hXVPN2urevZMAMtcTaCDFLWBaE1Q3jmdb1FHgve", + ], + "capabilityInvocation": Array [ + "did:key:zrusAFgBbf84b8mBz8Cmy8UoFWKV52EaeRnK86vnLo4Z5QoRypE6hXVPN2urevZMAMtcTaCDFLWBaE1Q3jmdb1FHgve#zrusAFgBbf84b8mBz8Cmy8UoFWKV52EaeRnK86vnLo4Z5QoRypE6hXVPN2urevZMAMtcTaCDFLWBaE1Q3jmdb1FHgve", + ], + "id": "did:key:zrusAFgBbf84b8mBz8Cmy8UoFWKV52EaeRnK86vnLo4Z5QoRypE6hXVPN2urevZMAMtcTaCDFLWBaE1Q3jmdb1FHgve", + "verificationMethod": Array [ + Object { + "controller": "did:key:zrusAFgBbf84b8mBz8Cmy8UoFWKV52EaeRnK86vnLo4Z5QoRypE6hXVPN2urevZMAMtcTaCDFLWBaE1Q3jmdb1FHgve", + "id": "did:key:zrusAFgBbf84b8mBz8Cmy8UoFWKV52EaeRnK86vnLo4Z5QoRypE6hXVPN2urevZMAMtcTaCDFLWBaE1Q3jmdb1FHgve#zrusAFgBbf84b8mBz8Cmy8UoFWKV52EaeRnK86vnLo4Z5QoRypE6hXVPN2urevZMAMtcTaCDFLWBaE1Q3jmdb1FHgve", + "publicKeyJwk": Object { + "crv": "P-256", + "kty": "EC", + "x": "igrFmi0whuihKnj9R3Om1SoMph72wUGeFaBbzG2vzns", + "y": "efsX5b10x8yjyrj4ny3pGfLcY7Xby1KzgqOdqnsrJIM", + }, + "type": "JsonWebKey2020", + }, + ], +} +`; + +exports[`Secp256r1 mapper successfully resolves the document from did:key from raw public key #3 1`] = ` +Object { + "assertionMethod": Array [ + "did:key:zrurwcJZss4ruepVNu1H3xmSirvNbzgBk9qrCktB6kaewXnJAhYWwtP3bxACqBpzjZdN7TyHNzzGGSSH5qvZsSDir9z#zrurwcJZss4ruepVNu1H3xmSirvNbzgBk9qrCktB6kaewXnJAhYWwtP3bxACqBpzjZdN7TyHNzzGGSSH5qvZsSDir9z", + ], + "authentication": Array [ + "did:key:zrurwcJZss4ruepVNu1H3xmSirvNbzgBk9qrCktB6kaewXnJAhYWwtP3bxACqBpzjZdN7TyHNzzGGSSH5qvZsSDir9z#zrurwcJZss4ruepVNu1H3xmSirvNbzgBk9qrCktB6kaewXnJAhYWwtP3bxACqBpzjZdN7TyHNzzGGSSH5qvZsSDir9z", + ], + "capabilityDelegation": Array [ + "did:key:zrurwcJZss4ruepVNu1H3xmSirvNbzgBk9qrCktB6kaewXnJAhYWwtP3bxACqBpzjZdN7TyHNzzGGSSH5qvZsSDir9z#zrurwcJZss4ruepVNu1H3xmSirvNbzgBk9qrCktB6kaewXnJAhYWwtP3bxACqBpzjZdN7TyHNzzGGSSH5qvZsSDir9z", + ], + "capabilityInvocation": Array [ + "did:key:zrurwcJZss4ruepVNu1H3xmSirvNbzgBk9qrCktB6kaewXnJAhYWwtP3bxACqBpzjZdN7TyHNzzGGSSH5qvZsSDir9z#zrurwcJZss4ruepVNu1H3xmSirvNbzgBk9qrCktB6kaewXnJAhYWwtP3bxACqBpzjZdN7TyHNzzGGSSH5qvZsSDir9z", + ], + "id": "did:key:zrurwcJZss4ruepVNu1H3xmSirvNbzgBk9qrCktB6kaewXnJAhYWwtP3bxACqBpzjZdN7TyHNzzGGSSH5qvZsSDir9z", + "verificationMethod": Array [ + Object { + "controller": "did:key:zrurwcJZss4ruepVNu1H3xmSirvNbzgBk9qrCktB6kaewXnJAhYWwtP3bxACqBpzjZdN7TyHNzzGGSSH5qvZsSDir9z", + "id": "did:key:zrurwcJZss4ruepVNu1H3xmSirvNbzgBk9qrCktB6kaewXnJAhYWwtP3bxACqBpzjZdN7TyHNzzGGSSH5qvZsSDir9z#zrurwcJZss4ruepVNu1H3xmSirvNbzgBk9qrCktB6kaewXnJAhYWwtP3bxACqBpzjZdN7TyHNzzGGSSH5qvZsSDir9z", + "publicKeyJwk": Object { + "crv": "P-256", + "kty": "EC", + "x": "fyNYMN0976ci7xqiSdag3buk-ZCwgXU4kz9XNkBlNUI", + "y": "hW2ojTNfH7Jbi8--CJUo3OCbH3y5n91g-IMA9MLMbTU", + }, + "type": "JsonWebKey2020", + }, + ], +} +`; + +exports[`Secp256r1 mapper successfully resolves the document from did:key from raw public key 1`] = ` +Object { + "assertionMethod": Array [ + "did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ#zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ", + ], + "authentication": Array [ + "did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ#zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ", + ], + "capabilityDelegation": Array [ + "did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ#zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ", + ], + "capabilityInvocation": Array [ + "did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ#zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ", + ], + "id": "did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ", + "verificationMethod": Array [ + Object { + "controller": "did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ", + "id": "did:key:zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ#zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ", + "publicKeyJwk": Object { + "crv": "P-256", + "kty": "EC", + "x": "-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y", + "y": "HNNnF7isXk_qitI9yNB4PCMY7krXqA224AJq0LByok8", }, "type": "JsonWebKey2020", }, @@ -62,7 +186,7 @@ Object { } `; -exports[`Secp256r1 mapper successfully resolves the document from did 3`] = ` +exports[`Secp256r1 mapper successfully resolves the document from did:key from uncompressed public key 1`] = ` Object { "assertionMethod": Array [ "did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY#z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", @@ -84,8 +208,8 @@ Object { "publicKeyJwk": Object { "crv": "P-256", "kty": "EC", - "x": "u-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y", - "y": "uHNNnF7isXk_qitI9yNB4PCMY7krXqA224AJq0LByok8", + "x": "-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y", + "y": "HNNnF7isXk_qitI9yNB4PCMY7krXqA224AJq0LByok8", }, "type": "JsonWebKey2020", }, diff --git a/packages/key-did-resolver/src/__tests__/__snapshots__/secp384r1.test.ts.snap b/packages/key-did-resolver/src/__tests__/__snapshots__/secp384r1.test.ts.snap new file mode 100644 index 0000000000..0ab6483c3d --- /dev/null +++ b/packages/key-did-resolver/src/__tests__/__snapshots__/secp384r1.test.ts.snap @@ -0,0 +1,249 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Secp384r1 mapper Secp384r1 mapper successfully resolves the document from did:key from compressed public key #2 1`] = ` +Object { + "assertionMethod": Array [ + "did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54#z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54", + ], + "authentication": Array [ + "did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54#z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54", + ], + "capabilityDelegation": Array [ + "did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54#z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54", + ], + "capabilityInvocation": Array [ + "did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54#z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54", + ], + "id": "did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54", + "verificationMethod": Array [ + Object { + "controller": "did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54", + "id": "did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54#z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54", + "publicKeyJwk": Object { + "crv": "P-384", + "kty": "EC", + "x": "CA-iNoHDg1lL8pvX3d1uvExzVfCz7Rn6tW781Ub8K5MrDf2IMPyL0RTDiaLHC1JT", + "y": "Kpnrn8DkXUD3ge4mFxi-DKr0DYO2KuJdwNBrhzLRtfMa3WFMZBiPKUPfJj8dYNl_", + }, + "type": "JsonWebKey2020", + }, + ], +} +`; + +exports[`Secp384r1 mapper Secp384r1 mapper successfully resolves the document from did:key from compressed public key #3 1`] = ` +Object { + "assertionMethod": Array [ + "did:key:z82Lm2BuneDPATu4BSWzhZwuandHAwY4DJrv3gAbo8RvG6yBTLJx6AhgoSmKy8XSK4HaPvA#z82Lm2BuneDPATu4BSWzhZwuandHAwY4DJrv3gAbo8RvG6yBTLJx6AhgoSmKy8XSK4HaPvA", + ], + "authentication": Array [ + "did:key:z82Lm2BuneDPATu4BSWzhZwuandHAwY4DJrv3gAbo8RvG6yBTLJx6AhgoSmKy8XSK4HaPvA#z82Lm2BuneDPATu4BSWzhZwuandHAwY4DJrv3gAbo8RvG6yBTLJx6AhgoSmKy8XSK4HaPvA", + ], + "capabilityDelegation": Array [ + "did:key:z82Lm2BuneDPATu4BSWzhZwuandHAwY4DJrv3gAbo8RvG6yBTLJx6AhgoSmKy8XSK4HaPvA#z82Lm2BuneDPATu4BSWzhZwuandHAwY4DJrv3gAbo8RvG6yBTLJx6AhgoSmKy8XSK4HaPvA", + ], + "capabilityInvocation": Array [ + "did:key:z82Lm2BuneDPATu4BSWzhZwuandHAwY4DJrv3gAbo8RvG6yBTLJx6AhgoSmKy8XSK4HaPvA#z82Lm2BuneDPATu4BSWzhZwuandHAwY4DJrv3gAbo8RvG6yBTLJx6AhgoSmKy8XSK4HaPvA", + ], + "id": "did:key:z82Lm2BuneDPATu4BSWzhZwuandHAwY4DJrv3gAbo8RvG6yBTLJx6AhgoSmKy8XSK4HaPvA", + "verificationMethod": Array [ + Object { + "controller": "did:key:z82Lm2BuneDPATu4BSWzhZwuandHAwY4DJrv3gAbo8RvG6yBTLJx6AhgoSmKy8XSK4HaPvA", + "id": "did:key:z82Lm2BuneDPATu4BSWzhZwuandHAwY4DJrv3gAbo8RvG6yBTLJx6AhgoSmKy8XSK4HaPvA#z82Lm2BuneDPATu4BSWzhZwuandHAwY4DJrv3gAbo8RvG6yBTLJx6AhgoSmKy8XSK4HaPvA", + "publicKeyJwk": Object { + "crv": "P-384", + "kty": "EC", + "x": "qyUMSOYczyVlnIxFi-nVGRpjs1BY7BIxVCOeq3WAopZN0OVZxG7WKe0kCbZ2zHkr", + "y": "7B9EM5quaUrqZ75_RzkAgS13NBDRBNRaSjK5jq1XP4OvNiBu2s1oMnOawysGikBP", + }, + "type": "JsonWebKey2020", + }, + ], +} +`; + +exports[`Secp384r1 mapper Secp384r1 mapper successfully resolves the document from did:key from compressed public key 1`] = ` +Object { + "assertionMethod": Array [ + "did:key:z82Lm1MpAkeJcix9K8TMiLd5NMAhnwkjjCBeWHXyu3U4oT2MVJJKXkcVBgjGhnLBn2Kaau9#z82Lm1MpAkeJcix9K8TMiLd5NMAhnwkjjCBeWHXyu3U4oT2MVJJKXkcVBgjGhnLBn2Kaau9", + ], + "authentication": Array [ + "did:key:z82Lm1MpAkeJcix9K8TMiLd5NMAhnwkjjCBeWHXyu3U4oT2MVJJKXkcVBgjGhnLBn2Kaau9#z82Lm1MpAkeJcix9K8TMiLd5NMAhnwkjjCBeWHXyu3U4oT2MVJJKXkcVBgjGhnLBn2Kaau9", + ], + "capabilityDelegation": Array [ + "did:key:z82Lm1MpAkeJcix9K8TMiLd5NMAhnwkjjCBeWHXyu3U4oT2MVJJKXkcVBgjGhnLBn2Kaau9#z82Lm1MpAkeJcix9K8TMiLd5NMAhnwkjjCBeWHXyu3U4oT2MVJJKXkcVBgjGhnLBn2Kaau9", + ], + "capabilityInvocation": Array [ + "did:key:z82Lm1MpAkeJcix9K8TMiLd5NMAhnwkjjCBeWHXyu3U4oT2MVJJKXkcVBgjGhnLBn2Kaau9#z82Lm1MpAkeJcix9K8TMiLd5NMAhnwkjjCBeWHXyu3U4oT2MVJJKXkcVBgjGhnLBn2Kaau9", + ], + "id": "did:key:z82Lm1MpAkeJcix9K8TMiLd5NMAhnwkjjCBeWHXyu3U4oT2MVJJKXkcVBgjGhnLBn2Kaau9", + "verificationMethod": Array [ + Object { + "controller": "did:key:z82Lm1MpAkeJcix9K8TMiLd5NMAhnwkjjCBeWHXyu3U4oT2MVJJKXkcVBgjGhnLBn2Kaau9", + "id": "did:key:z82Lm1MpAkeJcix9K8TMiLd5NMAhnwkjjCBeWHXyu3U4oT2MVJJKXkcVBgjGhnLBn2Kaau9#z82Lm1MpAkeJcix9K8TMiLd5NMAhnwkjjCBeWHXyu3U4oT2MVJJKXkcVBgjGhnLBn2Kaau9", + "publicKeyJwk": Object { + "crv": "P-384", + "kty": "EC", + "x": "lInTxl8fjLKp_UCrxI0WDklahi-7-_6JbtiHjiRvMvhedhKVdHBfi2HCY8t_QJyc", + "y": "y6N1IC-2mXxHreETBW7K3mBcw0qGr3CWHCs-yl09yCQRLcyfGv7XhqAngHOu51Zv", + }, + "type": "JsonWebKey2020", + }, + ], +} +`; + +exports[`Secp384r1 mapper Secp384r1 mapper successfully resolves the document from did:key from raw public key #2 1`] = ` +Object { + "assertionMethod": Array [ + "did:key:zFwepbBSaPFjt5T1zWptHaXugLNxHYABfJrDoAZRYxKjNkpdfrniF3pvYQAXwxVB7afhmsgzYtSCzTVZQ3F5SPHzP5PuHgtBGNYucZTSrnA7yTTDr7WGQZaTTkJWfiH47jW5ahU#zFwepbBSaPFjt5T1zWptHaXugLNxHYABfJrDoAZRYxKjNkpdfrniF3pvYQAXwxVB7afhmsgzYtSCzTVZQ3F5SPHzP5PuHgtBGNYucZTSrnA7yTTDr7WGQZaTTkJWfiH47jW5ahU", + ], + "authentication": Array [ + "did:key:zFwepbBSaPFjt5T1zWptHaXugLNxHYABfJrDoAZRYxKjNkpdfrniF3pvYQAXwxVB7afhmsgzYtSCzTVZQ3F5SPHzP5PuHgtBGNYucZTSrnA7yTTDr7WGQZaTTkJWfiH47jW5ahU#zFwepbBSaPFjt5T1zWptHaXugLNxHYABfJrDoAZRYxKjNkpdfrniF3pvYQAXwxVB7afhmsgzYtSCzTVZQ3F5SPHzP5PuHgtBGNYucZTSrnA7yTTDr7WGQZaTTkJWfiH47jW5ahU", + ], + "capabilityDelegation": Array [ + "did:key:zFwepbBSaPFjt5T1zWptHaXugLNxHYABfJrDoAZRYxKjNkpdfrniF3pvYQAXwxVB7afhmsgzYtSCzTVZQ3F5SPHzP5PuHgtBGNYucZTSrnA7yTTDr7WGQZaTTkJWfiH47jW5ahU#zFwepbBSaPFjt5T1zWptHaXugLNxHYABfJrDoAZRYxKjNkpdfrniF3pvYQAXwxVB7afhmsgzYtSCzTVZQ3F5SPHzP5PuHgtBGNYucZTSrnA7yTTDr7WGQZaTTkJWfiH47jW5ahU", + ], + "capabilityInvocation": Array [ + "did:key:zFwepbBSaPFjt5T1zWptHaXugLNxHYABfJrDoAZRYxKjNkpdfrniF3pvYQAXwxVB7afhmsgzYtSCzTVZQ3F5SPHzP5PuHgtBGNYucZTSrnA7yTTDr7WGQZaTTkJWfiH47jW5ahU#zFwepbBSaPFjt5T1zWptHaXugLNxHYABfJrDoAZRYxKjNkpdfrniF3pvYQAXwxVB7afhmsgzYtSCzTVZQ3F5SPHzP5PuHgtBGNYucZTSrnA7yTTDr7WGQZaTTkJWfiH47jW5ahU", + ], + "id": "did:key:zFwepbBSaPFjt5T1zWptHaXugLNxHYABfJrDoAZRYxKjNkpdfrniF3pvYQAXwxVB7afhmsgzYtSCzTVZQ3F5SPHzP5PuHgtBGNYucZTSrnA7yTTDr7WGQZaTTkJWfiH47jW5ahU", + "verificationMethod": Array [ + Object { + "controller": "did:key:zFwepbBSaPFjt5T1zWptHaXugLNxHYABfJrDoAZRYxKjNkpdfrniF3pvYQAXwxVB7afhmsgzYtSCzTVZQ3F5SPHzP5PuHgtBGNYucZTSrnA7yTTDr7WGQZaTTkJWfiH47jW5ahU", + "id": "did:key:zFwepbBSaPFjt5T1zWptHaXugLNxHYABfJrDoAZRYxKjNkpdfrniF3pvYQAXwxVB7afhmsgzYtSCzTVZQ3F5SPHzP5PuHgtBGNYucZTSrnA7yTTDr7WGQZaTTkJWfiH47jW5ahU#zFwepbBSaPFjt5T1zWptHaXugLNxHYABfJrDoAZRYxKjNkpdfrniF3pvYQAXwxVB7afhmsgzYtSCzTVZQ3F5SPHzP5PuHgtBGNYucZTSrnA7yTTDr7WGQZaTTkJWfiH47jW5ahU", + "publicKeyJwk": Object { + "crv": "P-384", + "kty": "EC", + "x": "CA-iNoHDg1lL8pvX3d1uvExzVfCz7Rn6tW781Ub8K5MrDf2IMPyL0RTDiaLHC1JT", + "y": "Kpnrn8DkXUD3ge4mFxi-DKr0DYO2KuJdwNBrhzLRtfMa3WFMZBiPKUPfJj8dYNl_", + }, + "type": "JsonWebKey2020", + }, + ], +} +`; + +exports[`Secp384r1 mapper Secp384r1 mapper successfully resolves the document from did:key from raw public key #3 1`] = ` +Object { + "assertionMethod": Array [ + "did:key:zFwfwzpxzCAUjJK6X7cLDFjxbp6G3iJy6AcntWLBu5SxJeGBjge7jVkmARyUqkJideMFofkhGF94wLopAmuqCH1JQ3fbzxmrBwKK52qF5w429kUJk5NdR8BJwDxpeWryV4oAH27#zFwfwzpxzCAUjJK6X7cLDFjxbp6G3iJy6AcntWLBu5SxJeGBjge7jVkmARyUqkJideMFofkhGF94wLopAmuqCH1JQ3fbzxmrBwKK52qF5w429kUJk5NdR8BJwDxpeWryV4oAH27", + ], + "authentication": Array [ + "did:key:zFwfwzpxzCAUjJK6X7cLDFjxbp6G3iJy6AcntWLBu5SxJeGBjge7jVkmARyUqkJideMFofkhGF94wLopAmuqCH1JQ3fbzxmrBwKK52qF5w429kUJk5NdR8BJwDxpeWryV4oAH27#zFwfwzpxzCAUjJK6X7cLDFjxbp6G3iJy6AcntWLBu5SxJeGBjge7jVkmARyUqkJideMFofkhGF94wLopAmuqCH1JQ3fbzxmrBwKK52qF5w429kUJk5NdR8BJwDxpeWryV4oAH27", + ], + "capabilityDelegation": Array [ + "did:key:zFwfwzpxzCAUjJK6X7cLDFjxbp6G3iJy6AcntWLBu5SxJeGBjge7jVkmARyUqkJideMFofkhGF94wLopAmuqCH1JQ3fbzxmrBwKK52qF5w429kUJk5NdR8BJwDxpeWryV4oAH27#zFwfwzpxzCAUjJK6X7cLDFjxbp6G3iJy6AcntWLBu5SxJeGBjge7jVkmARyUqkJideMFofkhGF94wLopAmuqCH1JQ3fbzxmrBwKK52qF5w429kUJk5NdR8BJwDxpeWryV4oAH27", + ], + "capabilityInvocation": Array [ + "did:key:zFwfwzpxzCAUjJK6X7cLDFjxbp6G3iJy6AcntWLBu5SxJeGBjge7jVkmARyUqkJideMFofkhGF94wLopAmuqCH1JQ3fbzxmrBwKK52qF5w429kUJk5NdR8BJwDxpeWryV4oAH27#zFwfwzpxzCAUjJK6X7cLDFjxbp6G3iJy6AcntWLBu5SxJeGBjge7jVkmARyUqkJideMFofkhGF94wLopAmuqCH1JQ3fbzxmrBwKK52qF5w429kUJk5NdR8BJwDxpeWryV4oAH27", + ], + "id": "did:key:zFwfwzpxzCAUjJK6X7cLDFjxbp6G3iJy6AcntWLBu5SxJeGBjge7jVkmARyUqkJideMFofkhGF94wLopAmuqCH1JQ3fbzxmrBwKK52qF5w429kUJk5NdR8BJwDxpeWryV4oAH27", + "verificationMethod": Array [ + Object { + "controller": "did:key:zFwfwzpxzCAUjJK6X7cLDFjxbp6G3iJy6AcntWLBu5SxJeGBjge7jVkmARyUqkJideMFofkhGF94wLopAmuqCH1JQ3fbzxmrBwKK52qF5w429kUJk5NdR8BJwDxpeWryV4oAH27", + "id": "did:key:zFwfwzpxzCAUjJK6X7cLDFjxbp6G3iJy6AcntWLBu5SxJeGBjge7jVkmARyUqkJideMFofkhGF94wLopAmuqCH1JQ3fbzxmrBwKK52qF5w429kUJk5NdR8BJwDxpeWryV4oAH27#zFwfwzpxzCAUjJK6X7cLDFjxbp6G3iJy6AcntWLBu5SxJeGBjge7jVkmARyUqkJideMFofkhGF94wLopAmuqCH1JQ3fbzxmrBwKK52qF5w429kUJk5NdR8BJwDxpeWryV4oAH27", + "publicKeyJwk": Object { + "crv": "P-384", + "kty": "EC", + "x": "xfAJIinIc0VwGlTcYxkkG6yts9HJcyrYJDHBm6TtWtXpci8sXFMU0xpYpzT96WVb", + "y": "Ygiq_i1DUlA8H0cBDwB-HafHEofMt6s6LR5-WZTPh1zj2VLz2MU4QV4FOPhEi3Go", + }, + "type": "JsonWebKey2020", + }, + ], +} +`; + +exports[`Secp384r1 mapper Secp384r1 mapper successfully resolves the document from did:key from raw public key 1`] = ` +Object { + "assertionMethod": Array [ + "did:key:zFwfeyrSyWdksRYykTGGtagWazFB5zS4CjQcxDMQSNmCTQB5QMqokx2VJz4vBB2hN1nUrYDTuYq3kd1BM5cUCfFD4awiNuzEBuoy6rZZTMCsZsdvWkDXY6832qcAnzE7YGw43KU#zFwfeyrSyWdksRYykTGGtagWazFB5zS4CjQcxDMQSNmCTQB5QMqokx2VJz4vBB2hN1nUrYDTuYq3kd1BM5cUCfFD4awiNuzEBuoy6rZZTMCsZsdvWkDXY6832qcAnzE7YGw43KU", + ], + "authentication": Array [ + "did:key:zFwfeyrSyWdksRYykTGGtagWazFB5zS4CjQcxDMQSNmCTQB5QMqokx2VJz4vBB2hN1nUrYDTuYq3kd1BM5cUCfFD4awiNuzEBuoy6rZZTMCsZsdvWkDXY6832qcAnzE7YGw43KU#zFwfeyrSyWdksRYykTGGtagWazFB5zS4CjQcxDMQSNmCTQB5QMqokx2VJz4vBB2hN1nUrYDTuYq3kd1BM5cUCfFD4awiNuzEBuoy6rZZTMCsZsdvWkDXY6832qcAnzE7YGw43KU", + ], + "capabilityDelegation": Array [ + "did:key:zFwfeyrSyWdksRYykTGGtagWazFB5zS4CjQcxDMQSNmCTQB5QMqokx2VJz4vBB2hN1nUrYDTuYq3kd1BM5cUCfFD4awiNuzEBuoy6rZZTMCsZsdvWkDXY6832qcAnzE7YGw43KU#zFwfeyrSyWdksRYykTGGtagWazFB5zS4CjQcxDMQSNmCTQB5QMqokx2VJz4vBB2hN1nUrYDTuYq3kd1BM5cUCfFD4awiNuzEBuoy6rZZTMCsZsdvWkDXY6832qcAnzE7YGw43KU", + ], + "capabilityInvocation": Array [ + "did:key:zFwfeyrSyWdksRYykTGGtagWazFB5zS4CjQcxDMQSNmCTQB5QMqokx2VJz4vBB2hN1nUrYDTuYq3kd1BM5cUCfFD4awiNuzEBuoy6rZZTMCsZsdvWkDXY6832qcAnzE7YGw43KU#zFwfeyrSyWdksRYykTGGtagWazFB5zS4CjQcxDMQSNmCTQB5QMqokx2VJz4vBB2hN1nUrYDTuYq3kd1BM5cUCfFD4awiNuzEBuoy6rZZTMCsZsdvWkDXY6832qcAnzE7YGw43KU", + ], + "id": "did:key:zFwfeyrSyWdksRYykTGGtagWazFB5zS4CjQcxDMQSNmCTQB5QMqokx2VJz4vBB2hN1nUrYDTuYq3kd1BM5cUCfFD4awiNuzEBuoy6rZZTMCsZsdvWkDXY6832qcAnzE7YGw43KU", + "verificationMethod": Array [ + Object { + "controller": "did:key:zFwfeyrSyWdksRYykTGGtagWazFB5zS4CjQcxDMQSNmCTQB5QMqokx2VJz4vBB2hN1nUrYDTuYq3kd1BM5cUCfFD4awiNuzEBuoy6rZZTMCsZsdvWkDXY6832qcAnzE7YGw43KU", + "id": "did:key:zFwfeyrSyWdksRYykTGGtagWazFB5zS4CjQcxDMQSNmCTQB5QMqokx2VJz4vBB2hN1nUrYDTuYq3kd1BM5cUCfFD4awiNuzEBuoy6rZZTMCsZsdvWkDXY6832qcAnzE7YGw43KU#zFwfeyrSyWdksRYykTGGtagWazFB5zS4CjQcxDMQSNmCTQB5QMqokx2VJz4vBB2hN1nUrYDTuYq3kd1BM5cUCfFD4awiNuzEBuoy6rZZTMCsZsdvWkDXY6832qcAnzE7YGw43KU", + "publicKeyJwk": Object { + "crv": "P-384", + "kty": "EC", + "x": "lInTxl8fjLKp_UCrxI0WDklahi-7-_6JbtiHjiRvMvhedhKVdHBfi2HCY8t_QJyc", + "y": "y6N1IC-2mXxHreETBW7K3mBcw0qGr3CWHCs-yl09yCQRLcyfGv7XhqAngHOu51Zv", + }, + "type": "JsonWebKey2020", + }, + ], +} +`; + +exports[`Secp384r1 mapper successfully resolves the document from did 1`] = ` +Object { + "assertionMethod": Array [ + "did:key:z28xDr9xiQCrXbooH2aC3eMVv74QKvxBgP1DHCMBWz6CvTHmdt4rtsH9JSHGsyPzdQpfMBJSSAHFh1zTjiyLhKchrMnNfBVEtCziwX2yy3YiQY9t6WcVUpSdVHaxeRz5x6JYoGGPJ#z28xDr9xiQCrXbooH2aC3eMVv74QKvxBgP1DHCMBWz6CvTHmdt4rtsH9JSHGsyPzdQpfMBJSSAHFh1zTjiyLhKchrMnNfBVEtCziwX2yy3YiQY9t6WcVUpSdVHaxeRz5x6JYoGGPJ", + ], + "authentication": Array [ + "did:key:z28xDr9xiQCrXbooH2aC3eMVv74QKvxBgP1DHCMBWz6CvTHmdt4rtsH9JSHGsyPzdQpfMBJSSAHFh1zTjiyLhKchrMnNfBVEtCziwX2yy3YiQY9t6WcVUpSdVHaxeRz5x6JYoGGPJ#z28xDr9xiQCrXbooH2aC3eMVv74QKvxBgP1DHCMBWz6CvTHmdt4rtsH9JSHGsyPzdQpfMBJSSAHFh1zTjiyLhKchrMnNfBVEtCziwX2yy3YiQY9t6WcVUpSdVHaxeRz5x6JYoGGPJ", + ], + "capabilityDelegation": Array [ + "did:key:z28xDr9xiQCrXbooH2aC3eMVv74QKvxBgP1DHCMBWz6CvTHmdt4rtsH9JSHGsyPzdQpfMBJSSAHFh1zTjiyLhKchrMnNfBVEtCziwX2yy3YiQY9t6WcVUpSdVHaxeRz5x6JYoGGPJ#z28xDr9xiQCrXbooH2aC3eMVv74QKvxBgP1DHCMBWz6CvTHmdt4rtsH9JSHGsyPzdQpfMBJSSAHFh1zTjiyLhKchrMnNfBVEtCziwX2yy3YiQY9t6WcVUpSdVHaxeRz5x6JYoGGPJ", + ], + "capabilityInvocation": Array [ + "did:key:z28xDr9xiQCrXbooH2aC3eMVv74QKvxBgP1DHCMBWz6CvTHmdt4rtsH9JSHGsyPzdQpfMBJSSAHFh1zTjiyLhKchrMnNfBVEtCziwX2yy3YiQY9t6WcVUpSdVHaxeRz5x6JYoGGPJ#z28xDr9xiQCrXbooH2aC3eMVv74QKvxBgP1DHCMBWz6CvTHmdt4rtsH9JSHGsyPzdQpfMBJSSAHFh1zTjiyLhKchrMnNfBVEtCziwX2yy3YiQY9t6WcVUpSdVHaxeRz5x6JYoGGPJ", + ], + "id": "did:key:z28xDr9xiQCrXbooH2aC3eMVv74QKvxBgP1DHCMBWz6CvTHmdt4rtsH9JSHGsyPzdQpfMBJSSAHFh1zTjiyLhKchrMnNfBVEtCziwX2yy3YiQY9t6WcVUpSdVHaxeRz5x6JYoGGPJ", + "verificationMethod": Array [ + Object { + "controller": "did:key:z28xDr9xiQCrXbooH2aC3eMVv74QKvxBgP1DHCMBWz6CvTHmdt4rtsH9JSHGsyPzdQpfMBJSSAHFh1zTjiyLhKchrMnNfBVEtCziwX2yy3YiQY9t6WcVUpSdVHaxeRz5x6JYoGGPJ", + "id": "did:key:z28xDr9xiQCrXbooH2aC3eMVv74QKvxBgP1DHCMBWz6CvTHmdt4rtsH9JSHGsyPzdQpfMBJSSAHFh1zTjiyLhKchrMnNfBVEtCziwX2yy3YiQY9t6WcVUpSdVHaxeRz5x6JYoGGPJ#z28xDr9xiQCrXbooH2aC3eMVv74QKvxBgP1DHCMBWz6CvTHmdt4rtsH9JSHGsyPzdQpfMBJSSAHFh1zTjiyLhKchrMnNfBVEtCziwX2yy3YiQY9t6WcVUpSdVHaxeRz5x6JYoGGPJ", + "publicKeyJwk": Object { + "crv": "P-384", + "kty": "EC", + "x": "13jbi1YTx-7wOHlnZb2Ij6ynya1Je1_HNGBDsTabfqQTXZJkj4gG08np89c5ohnc", + "y": "cyFSEmvuLWzhsgRptQNEt-zdEo0DpQTFmSPpv6MR6D_J2dC_pK8MDEBqw1DjLpuB", + }, + "type": "JsonWebKey2020", + }, + ], +} +`; + +exports[`Secp384r1 mapper successfully resolves the document from did 2`] = ` +Object { + "assertionMethod": Array [ + "did:key:z28xDrNf4RYwmuLQmfFBWWwiaxZtqyfME8BGUHemrsKUn6ShdzCLZWq2ZhmmSpVK2rtSLoeA1CJjrwGjZ64yCjJ9odVTYDdAMSu2LsTL1c5ehyQdkatFonfv3d7VNCByDrqntBoVz#z28xDrNf4RYwmuLQmfFBWWwiaxZtqyfME8BGUHemrsKUn6ShdzCLZWq2ZhmmSpVK2rtSLoeA1CJjrwGjZ64yCjJ9odVTYDdAMSu2LsTL1c5ehyQdkatFonfv3d7VNCByDrqntBoVz", + ], + "authentication": Array [ + "did:key:z28xDrNf4RYwmuLQmfFBWWwiaxZtqyfME8BGUHemrsKUn6ShdzCLZWq2ZhmmSpVK2rtSLoeA1CJjrwGjZ64yCjJ9odVTYDdAMSu2LsTL1c5ehyQdkatFonfv3d7VNCByDrqntBoVz#z28xDrNf4RYwmuLQmfFBWWwiaxZtqyfME8BGUHemrsKUn6ShdzCLZWq2ZhmmSpVK2rtSLoeA1CJjrwGjZ64yCjJ9odVTYDdAMSu2LsTL1c5ehyQdkatFonfv3d7VNCByDrqntBoVz", + ], + "capabilityDelegation": Array [ + "did:key:z28xDrNf4RYwmuLQmfFBWWwiaxZtqyfME8BGUHemrsKUn6ShdzCLZWq2ZhmmSpVK2rtSLoeA1CJjrwGjZ64yCjJ9odVTYDdAMSu2LsTL1c5ehyQdkatFonfv3d7VNCByDrqntBoVz#z28xDrNf4RYwmuLQmfFBWWwiaxZtqyfME8BGUHemrsKUn6ShdzCLZWq2ZhmmSpVK2rtSLoeA1CJjrwGjZ64yCjJ9odVTYDdAMSu2LsTL1c5ehyQdkatFonfv3d7VNCByDrqntBoVz", + ], + "capabilityInvocation": Array [ + "did:key:z28xDrNf4RYwmuLQmfFBWWwiaxZtqyfME8BGUHemrsKUn6ShdzCLZWq2ZhmmSpVK2rtSLoeA1CJjrwGjZ64yCjJ9odVTYDdAMSu2LsTL1c5ehyQdkatFonfv3d7VNCByDrqntBoVz#z28xDrNf4RYwmuLQmfFBWWwiaxZtqyfME8BGUHemrsKUn6ShdzCLZWq2ZhmmSpVK2rtSLoeA1CJjrwGjZ64yCjJ9odVTYDdAMSu2LsTL1c5ehyQdkatFonfv3d7VNCByDrqntBoVz", + ], + "id": "did:key:z28xDrNf4RYwmuLQmfFBWWwiaxZtqyfME8BGUHemrsKUn6ShdzCLZWq2ZhmmSpVK2rtSLoeA1CJjrwGjZ64yCjJ9odVTYDdAMSu2LsTL1c5ehyQdkatFonfv3d7VNCByDrqntBoVz", + "verificationMethod": Array [ + Object { + "controller": "did:key:z28xDrNf4RYwmuLQmfFBWWwiaxZtqyfME8BGUHemrsKUn6ShdzCLZWq2ZhmmSpVK2rtSLoeA1CJjrwGjZ64yCjJ9odVTYDdAMSu2LsTL1c5ehyQdkatFonfv3d7VNCByDrqntBoVz", + "id": "did:key:z28xDrNf4RYwmuLQmfFBWWwiaxZtqyfME8BGUHemrsKUn6ShdzCLZWq2ZhmmSpVK2rtSLoeA1CJjrwGjZ64yCjJ9odVTYDdAMSu2LsTL1c5ehyQdkatFonfv3d7VNCByDrqntBoVz#z28xDrNf4RYwmuLQmfFBWWwiaxZtqyfME8BGUHemrsKUn6ShdzCLZWq2ZhmmSpVK2rtSLoeA1CJjrwGjZ64yCjJ9odVTYDdAMSu2LsTL1c5ehyQdkatFonfv3d7VNCByDrqntBoVz", + "publicKeyJwk": Object { + "crv": "P-384", + "kty": "EC", + "x": "_FO6MCqEmTY2UV0ParU1tRp4UMtWnzJBGE10QA_M9oLA0rAgLlo6sSnR3hXI-Coa", + "y": "g7GFwNFlpQJ4W1pUrnYJQwQVbozZ0NjpNfAvGNlgkQui0VAFNe-0R8kUM2_wjYpp", + }, + "type": "JsonWebKey2020", + }, + ], +} +`; diff --git a/packages/key-did-resolver/src/__tests__/__snapshots__/secp521r1.test.ts.snap b/packages/key-did-resolver/src/__tests__/__snapshots__/secp521r1.test.ts.snap new file mode 100644 index 0000000000..ebad83dce4 --- /dev/null +++ b/packages/key-did-resolver/src/__tests__/__snapshots__/secp521r1.test.ts.snap @@ -0,0 +1,94 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Secp521r1 mapper successfully resolves the document from did 1`] = ` +Object { + "assertionMethod": Array [ + "did:key:z2J9gaYhkf4Ax2QA65KkcrSxr8JDSxUBwzFq3jmq5iBroY2tE7s1uohXVqEvALPxbvdzbWWQTtHvTprUdbNFha3HawyPcD9P#z2J9gaYhkf4Ax2QA65KkcrSxr8JDSxUBwzFq3jmq5iBroY2tE7s1uohXVqEvALPxbvdzbWWQTtHvTprUdbNFha3HawyPcD9P", + ], + "authentication": Array [ + "did:key:z2J9gaYhkf4Ax2QA65KkcrSxr8JDSxUBwzFq3jmq5iBroY2tE7s1uohXVqEvALPxbvdzbWWQTtHvTprUdbNFha3HawyPcD9P#z2J9gaYhkf4Ax2QA65KkcrSxr8JDSxUBwzFq3jmq5iBroY2tE7s1uohXVqEvALPxbvdzbWWQTtHvTprUdbNFha3HawyPcD9P", + ], + "capabilityDelegation": Array [ + "did:key:z2J9gaYhkf4Ax2QA65KkcrSxr8JDSxUBwzFq3jmq5iBroY2tE7s1uohXVqEvALPxbvdzbWWQTtHvTprUdbNFha3HawyPcD9P#z2J9gaYhkf4Ax2QA65KkcrSxr8JDSxUBwzFq3jmq5iBroY2tE7s1uohXVqEvALPxbvdzbWWQTtHvTprUdbNFha3HawyPcD9P", + ], + "capabilityInvocation": Array [ + "did:key:z2J9gaYhkf4Ax2QA65KkcrSxr8JDSxUBwzFq3jmq5iBroY2tE7s1uohXVqEvALPxbvdzbWWQTtHvTprUdbNFha3HawyPcD9P#z2J9gaYhkf4Ax2QA65KkcrSxr8JDSxUBwzFq3jmq5iBroY2tE7s1uohXVqEvALPxbvdzbWWQTtHvTprUdbNFha3HawyPcD9P", + ], + "id": "did:key:z2J9gaYhkf4Ax2QA65KkcrSxr8JDSxUBwzFq3jmq5iBroY2tE7s1uohXVqEvALPxbvdzbWWQTtHvTprUdbNFha3HawyPcD9P", + "verificationMethod": Array [ + Object { + "controller": "did:key:z2J9gaYhkf4Ax2QA65KkcrSxr8JDSxUBwzFq3jmq5iBroY2tE7s1uohXVqEvALPxbvdzbWWQTtHvTprUdbNFha3HawyPcD9P", + "id": "did:key:z2J9gaYhkf4Ax2QA65KkcrSxr8JDSxUBwzFq3jmq5iBroY2tE7s1uohXVqEvALPxbvdzbWWQTtHvTprUdbNFha3HawyPcD9P#z2J9gaYhkf4Ax2QA65KkcrSxr8JDSxUBwzFq3jmq5iBroY2tE7s1uohXVqEvALPxbvdzbWWQTtHvTprUdbNFha3HawyPcD9P", + "publicKeyJwk": Object { + "crv": "P-521", + "kty": "EC", + "x": "efE2eR719GHSoSzmtzVlBmaFD6wTYVg4r661VhHrxlqsatRDJr4628mgVowOitFEQMbz_osNgBn9tiIHW1YfYW4", + "y": "AcXkiFup65KvqBXF2r52zMTS-yjyOrQYFIDIPp870eRQEfo7tiID4EbosLY62BKmR74lG5pjnvTbA258IIUA3zO-", + }, + "type": "JsonWebKey2020", + }, + ], +} +`; + +exports[`Secp521r1 mapper successfully resolves the document from did 2`] = ` +Object { + "assertionMethod": Array [ + "did:key:z2J9gcGdbo8riFqfRzgo3gjJyFcbNJm75hrnpDrZTNqQQxgNVBTtKndBiKxzGXrAbyw5W88VDbR1B1FvRQNTnSezghqnJ7p6#z2J9gcGdbo8riFqfRzgo3gjJyFcbNJm75hrnpDrZTNqQQxgNVBTtKndBiKxzGXrAbyw5W88VDbR1B1FvRQNTnSezghqnJ7p6", + ], + "authentication": Array [ + "did:key:z2J9gcGdbo8riFqfRzgo3gjJyFcbNJm75hrnpDrZTNqQQxgNVBTtKndBiKxzGXrAbyw5W88VDbR1B1FvRQNTnSezghqnJ7p6#z2J9gcGdbo8riFqfRzgo3gjJyFcbNJm75hrnpDrZTNqQQxgNVBTtKndBiKxzGXrAbyw5W88VDbR1B1FvRQNTnSezghqnJ7p6", + ], + "capabilityDelegation": Array [ + "did:key:z2J9gcGdbo8riFqfRzgo3gjJyFcbNJm75hrnpDrZTNqQQxgNVBTtKndBiKxzGXrAbyw5W88VDbR1B1FvRQNTnSezghqnJ7p6#z2J9gcGdbo8riFqfRzgo3gjJyFcbNJm75hrnpDrZTNqQQxgNVBTtKndBiKxzGXrAbyw5W88VDbR1B1FvRQNTnSezghqnJ7p6", + ], + "capabilityInvocation": Array [ + "did:key:z2J9gcGdbo8riFqfRzgo3gjJyFcbNJm75hrnpDrZTNqQQxgNVBTtKndBiKxzGXrAbyw5W88VDbR1B1FvRQNTnSezghqnJ7p6#z2J9gcGdbo8riFqfRzgo3gjJyFcbNJm75hrnpDrZTNqQQxgNVBTtKndBiKxzGXrAbyw5W88VDbR1B1FvRQNTnSezghqnJ7p6", + ], + "id": "did:key:z2J9gcGdbo8riFqfRzgo3gjJyFcbNJm75hrnpDrZTNqQQxgNVBTtKndBiKxzGXrAbyw5W88VDbR1B1FvRQNTnSezghqnJ7p6", + "verificationMethod": Array [ + Object { + "controller": "did:key:z2J9gcGdbo8riFqfRzgo3gjJyFcbNJm75hrnpDrZTNqQQxgNVBTtKndBiKxzGXrAbyw5W88VDbR1B1FvRQNTnSezghqnJ7p6", + "id": "did:key:z2J9gcGdbo8riFqfRzgo3gjJyFcbNJm75hrnpDrZTNqQQxgNVBTtKndBiKxzGXrAbyw5W88VDbR1B1FvRQNTnSezghqnJ7p6#z2J9gcGdbo8riFqfRzgo3gjJyFcbNJm75hrnpDrZTNqQQxgNVBTtKndBiKxzGXrAbyw5W88VDbR1B1FvRQNTnSezghqnJ7p6", + "publicKeyJwk": Object { + "crv": "P-521", + "kty": "EC", + "x": "AQhYV0yHhVL9n7sjCIxMjeQjQiy2F4lv3Qd7diAVP4xJW3kl1Na4aKIeEzYP3Un6ThoCxC-KFhHePvjM5QNk9mp7", + "y": "Aewp6gi7EiTP1tVqLCefC6gQ7BTxsY2t0D_qMXJPUoXqlihkyBMKA9CRFAXq16sfXhWFMckcnk-MLRjNC6XB4Pmj", + }, + "type": "JsonWebKey2020", + }, + ], +} +`; + +exports[`Secp521r1 mapper successfully resolves the document from did 3`] = ` +Object { + "assertionMethod": Array [ + "did:key:z2J9gcGTjd3NaNifwmaNZN27xioMAzHHCDBmkuQ552hm9kWrzhUepDCSAhiuRYBj1sSXR1LBxgqh6vasYzc8JhC12FpaNDhT#z2J9gcGTjd3NaNifwmaNZN27xioMAzHHCDBmkuQ552hm9kWrzhUepDCSAhiuRYBj1sSXR1LBxgqh6vasYzc8JhC12FpaNDhT", + ], + "authentication": Array [ + "did:key:z2J9gcGTjd3NaNifwmaNZN27xioMAzHHCDBmkuQ552hm9kWrzhUepDCSAhiuRYBj1sSXR1LBxgqh6vasYzc8JhC12FpaNDhT#z2J9gcGTjd3NaNifwmaNZN27xioMAzHHCDBmkuQ552hm9kWrzhUepDCSAhiuRYBj1sSXR1LBxgqh6vasYzc8JhC12FpaNDhT", + ], + "capabilityDelegation": Array [ + "did:key:z2J9gcGTjd3NaNifwmaNZN27xioMAzHHCDBmkuQ552hm9kWrzhUepDCSAhiuRYBj1sSXR1LBxgqh6vasYzc8JhC12FpaNDhT#z2J9gcGTjd3NaNifwmaNZN27xioMAzHHCDBmkuQ552hm9kWrzhUepDCSAhiuRYBj1sSXR1LBxgqh6vasYzc8JhC12FpaNDhT", + ], + "capabilityInvocation": Array [ + "did:key:z2J9gcGTjd3NaNifwmaNZN27xioMAzHHCDBmkuQ552hm9kWrzhUepDCSAhiuRYBj1sSXR1LBxgqh6vasYzc8JhC12FpaNDhT#z2J9gcGTjd3NaNifwmaNZN27xioMAzHHCDBmkuQ552hm9kWrzhUepDCSAhiuRYBj1sSXR1LBxgqh6vasYzc8JhC12FpaNDhT", + ], + "id": "did:key:z2J9gcGTjd3NaNifwmaNZN27xioMAzHHCDBmkuQ552hm9kWrzhUepDCSAhiuRYBj1sSXR1LBxgqh6vasYzc8JhC12FpaNDhT", + "verificationMethod": Array [ + Object { + "controller": "did:key:z2J9gcGTjd3NaNifwmaNZN27xioMAzHHCDBmkuQ552hm9kWrzhUepDCSAhiuRYBj1sSXR1LBxgqh6vasYzc8JhC12FpaNDhT", + "id": "did:key:z2J9gcGTjd3NaNifwmaNZN27xioMAzHHCDBmkuQ552hm9kWrzhUepDCSAhiuRYBj1sSXR1LBxgqh6vasYzc8JhC12FpaNDhT#z2J9gcGTjd3NaNifwmaNZN27xioMAzHHCDBmkuQ552hm9kWrzhUepDCSAhiuRYBj1sSXR1LBxgqh6vasYzc8JhC12FpaNDhT", + "publicKeyJwk": Object { + "crv": "P-521", + "kty": "EC", + "x": "mI3pqrt5mbpgyopw74-q4WX6M2FkUPgroJHo3l9eG6pVXesQm4K51-M2yoxjt_ap6MtsaP78F-gzcn_lh5t_q5I", + "y": "AQpsaMuiW3OjliI8bINPPmtK95KBXr7wOaPsFTh-J7pm-sMV83VrVJWCqGXaMbQNUIv3my2n34gk057_ZwFlkRSD", + }, + "type": "JsonWebKey2020", + }, + ], +} +`; diff --git a/packages/key-did-resolver/src/__tests__/index.test.ts b/packages/key-did-resolver/src/__tests__/index.test.ts index e9eb0d0802..8fe9efea45 100644 --- a/packages/key-did-resolver/src/__tests__/index.test.ts +++ b/packages/key-did-resolver/src/__tests__/index.test.ts @@ -79,8 +79,92 @@ describe('Index mapper', () => { doc = await resolve('did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY', parsedDid, {}, { accept: 'application/did+json' }) expect(doc).toMatchSnapshot() + parsedDid = { + id: "z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", + did: 'did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY', + method: "key", + didUrl: 'did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY/some/path', + path: '/some/path' + } + + doc = await resolve('did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY', parsedDid, {}, { accept: 'application/did+ld+json' }) + expect(doc).toMatchSnapshot() + + doc = await resolve('did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY', parsedDid, {}, { accept: 'application/did+json' }) + expect(doc).toMatchSnapshot() + + parsedDid = { + id: "z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54", + did: 'did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54', + method: "key", + didUrl: 'did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54/some/path', + path: '/some/path' + } + + doc = await resolve('did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54', parsedDid, {}, { accept: 'application/did+ld+json' }) + expect(doc).toMatchSnapshot() + + doc = await resolve('did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54', parsedDid, {}, { accept: 'application/did+json' }) + expect(doc).toMatchSnapshot() + }) }) +describe('Exception mapper', () => { + it('expect index.js to throw an error for an unsupported decentralized identifier', async () => { + const resolverRegistry = index.getResolver() + expect(resolverRegistry).not.toBeUndefined() + + const resolve = resolverRegistry.key + expect(resolve).not.toBeUndefined() + + const parsedDided25519 = { + id: "z6LSeu9HkTHSfLLeUs2nnzUSNedgDUevfNQgQjQC23ZCit6F", + did: 'did:key:z6LSeu9HkTHSfLLeUs2nnzUSNedgDUevfNQgQjQC23ZCit6F', + method: "key", + didUrl: 'did:key:z6LSeu9HkTHSfLLeUs2nnzUSNedgDUevfNQgQjQC23ZCit6F/some/path', + path: '/some/path' + } + await expect(resolve('did:key:z6LSeu9HkTHSfLLeUs2nnzUSNedgDUevfNQgQjQC23ZCit6F', parsedDided25519, {}, { accept: 'application/did+ld+json' })).resolves.toEqual({"didDocument": null, "didDocumentMetadata": {}, "didResolutionMetadata": {"contentType": "application/did+ld+json", "error": "invalidDid", "message": "TypeError: Cannot read property 'keyToDidDoc' of undefined"}}) + }) + + it('expect index.js to throw an error for an unsupported media type', async () => { + const resolverRegistry = index.getResolver() + expect(resolverRegistry).not.toBeUndefined() + + const resolve = resolverRegistry.key + expect(resolve).not.toBeUndefined() + + const parsedDided25519 = { + id: "z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8", + did: 'did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8', + method: "key", + didUrl: 'did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8/some/path', + path: '/some/path' + } + + await expect(resolve('did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8', parsedDided25519, {}, { accept: 'application/rdf+xml' })).resolves.toEqual({"didDocument": null, "didDocumentMetadata": {}, "didResolutionMetadata": {"error": "representationNotSupported"}}) + }) + + it('expect index.js to throw an error for an unsupported media type', async () => { + const resolverRegistry = index.getResolver() + expect(resolverRegistry).not.toBeUndefined() + + const resolve = resolverRegistry.key + expect(resolve).not.toBeUndefined() + + const parsedDided25519 = { + id: "z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8", + did: 'did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8', + method: "key", + didUrl: 'did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8/some/path', + path: '/some/path' + } + + await expect(resolve('did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8', parsedDided25519, {}, { accept: 'application/did+json' })).resolves.toEqual(expect.anything()) + + }) + +}) diff --git a/packages/key-did-resolver/src/__tests__/nist_weierstrass_common.test.ts b/packages/key-did-resolver/src/__tests__/nist_weierstrass_common.test.ts new file mode 100644 index 0000000000..972cddd54f --- /dev/null +++ b/packages/key-did-resolver/src/__tests__/nist_weierstrass_common.test.ts @@ -0,0 +1,458 @@ +// Brent Shambaugh . 2021. + +import * as mapper from "../nist_weierstrass_common" +import * as u8a from 'uint8arrays' + +test('test a hex string with unexpected input', () => { + const inputPublicKeyHex = ''; + const publicKey_u8a = mapper.testHexString(inputPublicKeyHex); + expect(publicKey_u8a).toEqual(false); +}); + +test('test a hex string with unexpected input : try 2', () => { + const inputPublicKeyHex = 99; + const publicKey_u8a = mapper.testHexString(inputPublicKeyHex); + expect(publicKey_u8a).toEqual(false); +}); + +test('test a hex string shorter than 33 bytes', () => { + const inputPublicKeyHex = 'abc09'; + const publicKey_u8a = mapper.testHexString(inputPublicKeyHex); + expect(publicKey_u8a).toEqual(true); +}); + +test('test testUint8Array with correct input', () => { + const inputCompressedPoint = Uint8Array.from([3,127,35,88,48,221,61,239,167,34,239,26,162,73,214,160,221,187,164,249,144,176,129,117,56,147,63,87,54,64,101,53,66]); + const publicKey_u8a = mapper.testUint8Array(inputCompressedPoint); + expect(publicKey_u8a).toEqual(true); +}); + +test('test testUint8Array with number', () => { + const inputCompressedPoint = 5; + const publicKey_u8a = mapper.testUint8Array(inputCompressedPoint); + expect(publicKey_u8a).toEqual(false); +}); + +test('test testUint8Array with number', () => { + const inputCompressedPoint = 'donkey'; + const publicKey_u8a = mapper.testUint8Array(inputCompressedPoint); + expect(publicKey_u8a).toEqual(false); +}); + +test('expect pubKeyBytesToHex to throw an error for null', () => { + expect(() => { + mapper.pubKeyBytesToHex(null); + }).toThrowError('input must be a Uint8Array'); +}); + +test('expect pubKeyBytesToHex to throw an error for undefined', () => { + expect(() => { + mapper.pubKeyBytesToHex(); + }).toThrowError('input must be a Uint8Array'); +}); + +test('expect pubKeyBytesToHex to throw an error for an unexpected integer', () => { + expect(() => { + mapper.pubKeyBytesToHex(5); + }).toThrowError('input must be a Uint8Array'); +}); + +test('expect pubKeyBytesToHex to throw an error for an unexpected object', () => { + expect(() => { + mapper.pubKeyBytesToHex({x: 6n, y: 5n}); + }).toThrowError('input must be a Uint8Array'); +}); + +test('expect pubKeyBytesToHex to convert byte array to hex string', () => { + const output = '80247f235830dd3defa722ef1aa249d6a0ddbba4f990b0817538933f573640653542856da88d335f1fb25b8bcfbe089528dce09b1f7cb99fdd60f88300f4c2cc6d35'; + const input = Uint8Array.from([ + 128, 36, 127, 35, 88, 48, 221, 61, 239, 167, 34, + 239, 26, 162, 73, 214, 160, 221, 187, 164, 249, 144, + 176, 129, 117, 56, 147, 63, 87, 54, 64, 101, 53, + 66, 133, 109, 168, 141, 51, 95, 31, 178, 91, 139, + 207, 190, 8, 149, 40, 220, 224, 155, 31, 124, 185, + 159, 221, 96, 248, 131, 0, 244, 194, 204, 109, 53 + ]); + const result = mapper.pubKeyBytesToHex(input); + expect(result).toEqual(output); + }); + +test('expect publicKeyIntToXY to throw an error for incorrect type', () => { + expect(() => { + mapper.publicKeyIntToXY(5); + }).toThrowError('Input must be an object with properties x and y'); +}); + +test('expect publicKeyIntToXY to throw an error for {x: null, y: null}', () => { + expect(() => { + mapper.publicKeyIntToXY({x: null, y: null}); + }).toThrowError('Input coordinates must be BigInt'); +}); + +test('expect publicKeyIntToXY to throw an error for {x: undefined, y: undefined}', () => { + expect(() => { + mapper.publicKeyIntToXY(); + }).toThrow(); +}); + + +test('expect publicKeyHextToUint8ArrayPointPair to throw an error for {x: undefined, y: undefined}', () => { + expect(() => { + mapper.publicKeyHexToUint8ArrayPointPair(); + }).toThrowError('input must be string with characters 0-9,A-F,a-f'); +}); + + +test('expect publicKeyHexToUint8ArrayPointPair to throw an error for incorrect type', () => { + expect(() => { + mapper.publicKeyHexToUint8ArrayPointPair(5); + }).toThrowError('input must be string with characters 0-9,A-F,a-f'); +}); + + +test('expect publicKeyHexToUint8ArrayPointPair to throw an error for {x: null, y: null}', () => { + expect(() => { + mapper.publicKeyHexToUint8ArrayPointPair({x: null, y: null}); + }).toThrowError('input must be string with characters 0-9,A-F,a-f'); +}); + +test('expect publicKeyHexToUint8ArrayPointPair to throw an error for {x: undefined, y: undefined}', () => { + expect(() => { + mapper.publicKeyHexToUint8ArrayPointPair({x: undefined, y: undefined}); + }).toThrowError('input must be string with characters 0-9,A-F,a-f'); +}); + +test('expect publicKeyHexToUint8ArrayPointPair to throw an error for null', () => { + expect(() => { + mapper.publicKeyHexToUint8ArrayPointPair(null); + }).toThrowError('input must be string with characters 0-9,A-F,a-f'); +}); + +test('expect publicKeyToXY to throw an error for null', () => { + expect(() => { + mapper.publicKeyToXY(null); + }).toThrowError('input must be string with characters 0-9,A-F,a-f'); +}); + +test('expect publicKeyToXY to throw an error for undefined', () => { + expect(() => { + mapper.publicKeyToXY(); + }).toThrowError('input must be string with characters 0-9,A-F,a-f'); +}); + +test('expect publicKeyToXY to throw an error for a non string', () => { + expect(() => { + mapper.publicKeyToXY(5); + }).toThrowError('input must be string with characters 0-9,A-F,a-f'); +}); + +test('expect publicKeyToXY to throw an error for an invalid hex string', () => { + expect(() => { + mapper.publicKeyToXY('095ty'); + }).toThrowError('input must be string with characters 0-9,A-F,a-f'); +}); + +test('empty key string to should not evaluate to null, or should it??', () => { + const inputPublicKeyHex = ''; + expect(() => { + mapper.publicKeyHexToUint8ArrayPointPair(inputPublicKeyHex); + }).toThrowError('input must be string with characters 0-9,A-F,a-f'); + }); + +test('test a hex string shorter than 33 bytes', () => { + const inputPublicKeyHex = '36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb6' + const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); + expect(publicKey_u8a).not.toEqual(null); +}); + +test('test a compressed public key in hex with an odd number of characters', () => { + const inputPublicKeyHex = '2f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb6'; + const output = Uint8Array.from([2,249,195,111,137,100,98,51,120,189,192,104,212,188,224,126,209,124,143,164,134,249,172,12,38,19,202,60,140,48, 109, 123, 182]); + const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); + expect(publicKey_u8a).toEqual(output); +}); + +test('convert a public key x,y where x and y are integers to an x,y point with x and y base64url encoded', () => { + const ecpoint = { + x: 112971204272793929541699765384018665134067875121047561926148644683187420494774n, + y: 13038276010400560657327464707708345466200402936352359974176190171319880557135n + }; + const output = { + xm: '-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y', + ym: 'HNNnF7isXk_qitI9yNB4PCMY7krXqA224AJq0LByok8' + }; + + const base64urlPoint = mapper.publicKeyIntToXY(ecpoint); + expect(base64urlPoint).toEqual(output); + +}); + + +test('convert raw public key as a hex string into an x,y point with x and y base64url encoded', () => { + const inputPublicKeyHex = 'f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb61cd36717b8ac5e4fea8ad23dc8d0783c2318ee4ad7a80db6e0026ad0b072a24f' + const output = { + xm: '-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y', + ym: 'HNNnF7isXk_qitI9yNB4PCMY7krXqA224AJq0LByok8' + }; + const base64urlPoint = mapper.publicKeyToXY(inputPublicKeyHex); + expect(base64urlPoint).toEqual(output); +}); + +test('expect publicKeyIntToXY to throw an error for incorrect type', () => { + expect(() => { + mapper.publicKeyIntToXY(5); + }).toThrowError('Input must be an object with properties x and y'); +}); + +test('expect publicKeyIntToXY to throw an error for {x: null, y: null}', () => { + expect(() => { + mapper.publicKeyIntToXY({x: null, y: null}); + }).toThrowError('Input coordinates must be BigInt'); +}); + +test('expect publicKeyIntToXY to have properties x and y', () => { + expect(() => { + mapper.publicKeyIntToXY({x: 5n, z: 8n}); + }).toThrowError('Input must have properties x and y'); +}); + +test('expect publicKeyIntToXY to throw an error for {x: undefined, y: undefined}', () => { + expect(() => { + mapper.publicKeyIntToXY(); + }).toThrowError('input cannot be null or undefined.'); +}); + +test('expect publicKeyIntToUint8ArrayPointPair to throw an error for {x: undefined, y: undefined}', () => { + expect(() => { + mapper.publicKeyHexToUint8ArrayPointPair(); + }).toThrowError('input must be string with characters 0-9,A-F,a-f'); +}); + +test('expect publicKeyIntToUint8ArrayPointPair to throw an error for {x: 5, y: 9}', () => { + expect(() => { + mapper.publicKeyIntToUint8ArrayPointPair({x: 5,y: 9}); + }).toThrowError('Input coordinates must be BigInt'); +}); + +test('expect publicKeyIntToUint8ArrayPointPair to throw an error for null', () => { + expect(() => { + mapper.publicKeyIntToUint8ArrayPointPair(null); + }).toThrowError('input cannot be null or undefined.'); +}); + +test('expect publicKeyIntToUint8ArrayPointPair to throw an error for mislabled coordinate properties', () => { + expect(() => { + mapper.publicKeyIntToUint8ArrayPointPair({x: 5n, z: 7n}); + }).toThrowError('Input must have properties x and y'); +}); + +test('expect publicKeyIntToUint8ArrayPointPair to throw an error for a non object', () => { + expect(() => { + mapper.publicKeyIntToUint8ArrayPointPair(6); + }).toThrowError('Input must be an object with properties x and y'); +}); + +test('convert a public key x,y where x and y are integers to a pair of Uint8Arrays', () => { + const ecpoint = { + x: 112971204272793929541699765384018665134067875121047561926148644683187420494774n, + y: 13038276010400560657327464707708345466200402936352359974176190171319880557135n + }; + const output = { xOctet : Uint8Array.from([ + 249, 195, 111, 137, 100, 98, 51, + 120, 189, 192, 104, 212, 188, 224, + 126, 209, 124, 143, 164, 134, 249, + 172, 12, 38, 19, 202, 60, 140, + 48, 109, 123, 182 + ] ) , + yOctet : Uint8Array.from([ + 28, 211, 103, 23, 184, 172, 94, 79, + 234, 138, 210, 61, 200, 208, 120, 60, + 35, 24, 238, 74, 215, 168, 13, 182, + 224, 2, 106, 208, 176, 114, 162, 79 + ] ) + }; + + const u8aPoint = mapper.publicKeyIntToUint8ArrayPointPair(ecpoint); + expect(u8aPoint).toEqual(output); +}); + +test('key compression (y-coordinate even)', () => { + // inputPublicKeyHex derived from: https://stackoverflow.com/questions/67135136/unable-to-verify-a-raw-uint8array-ecdsa-secp256r1-message-signature-pubkey-usi + + const inputPublicKeyHex = '39c3dd74131729446dc1b3da67d49fc046fcbf072fcc5b9fa51c05b974307f969c403b1635f0449f02bd422751e33121a4434f152f2b2b2a3f675219c5d925f6' + const output = Uint8Array.from([2,57,195,221,116,19,23,41,68,109,193,179,218,103,212,159,192,70,252,191,7,47,204,91,159,165,28,5,185,116,48,127,150]); + + const u8aPoint = mapper.publicKeyHexToUint8ArrayPointPair(inputPublicKeyHex); + const compressedPoint = ECPointCompress(u8aPoint.xOctet, u8aPoint.yOctet); + + expect(compressedPoint).toEqual(output); + +}); + +test('key compression (y-coordinate odd) key#2', () => { + const inputPublicKeyHex = '7f235830dd3defa722ef1aa249d6a0ddbba4f990b0817538933f573640653542856da88d335f1fb25b8bcfbe089528dce09b1f7cb99fdd60f88300f4c2cc6d35' + const output = Uint8Array.from([3,127,35,88,48,221,61,239,167,34,239,26,162,73,214,160,221,187,164,249,144,176,129,117,56,147,63,87,54,64,101,53,66]); + + const u8aPoint = mapper.publicKeyHexToUint8ArrayPointPair(inputPublicKeyHex); + const compressedPoint = ECPointCompress(u8aPoint.xOctet, u8aPoint.yOctet); + + expect(compressedPoint).toEqual(output); +}); + +test('key compression (y-coordinate odd)', () => { + const inputPublicKeyHex = 'f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb61cd36717b8ac5e4fea8ad23dc8d0783c2318ee4ad7a80db6e0026ad0b072a24f' + const output = Uint8Array.from([3,249,195,111,137,100,98,51,120,189,192,104,212,188,224,126,209,124,143,164,134,249,172,12,38,19,202,60,140,48,109,123,182]); + + const u8aPoint = mapper.publicKeyHexToUint8ArrayPointPair(inputPublicKeyHex); + const compressedPoint = ECPointCompress(u8aPoint.xOctet, u8aPoint.yOctet); + + expect(compressedPoint).toEqual(output); +}); + +test('raw public key as hex string to x,y point with x and y as uint8Arrays', () => { + const inputPublicKeyHex = 'f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb61cd36717b8ac5e4fea8ad23dc8d0783c2318ee4ad7a80db6e0026ad0b072a24f' + const output = { xOctet : Uint8Array.from([ + 249, 195, 111, 137, 100, 98, 51, + 120, 189, 192, 104, 212, 188, 224, + 126, 209, 124, 143, 164, 134, 249, + 172, 12, 38, 19, 202, 60, 140, + 48, 109, 123, 182 + ] ) , + yOctet : Uint8Array.from([ + 28, 211, 103, 23, 184, 172, 94, 79, + 234, 138, 210, 61, 200, 208, 120, 60, + 35, 24, 238, 74, 215, 168, 13, 182, + 224, 2, 106, 208, 176, 114, 162, 79 + ] ) + }; + + const u8aPoint = mapper.publicKeyHexToUint8ArrayPointPair(inputPublicKeyHex); + expect(u8aPoint).toEqual(output); +}); + +test('show how to compress a raw public key in hex and return a compressed key in hex', () => { + const inputPublicKeyHex = 'f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb61cd36717b8ac5e4fea8ad23dc8d0783c2318ee4ad7a80db6e0026ad0b072a24f'; + const output = '03f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb6'; + const compresedKey = compresedKeyInHex(inputPublicKeyHex); + expect(compresedKey).toEqual(output); +}); + +test('show how to convert a raw public key in hex and return an uncompressed key in hex', () => { + const inputPublicKeyHex = 'f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb61cd36717b8ac5e4fea8ad23dc8d0783c2318ee4ad7a80db6e0026ad0b072a24f'; + const output = '04f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb61cd36717b8ac5e4fea8ad23dc8d0783c2318ee4ad7a80db6e0026ad0b072a24f'; + const uncompressedKey = '04'+ inputPublicKeyHex; + expect(uncompressedKey).toEqual(output); +}); + +/* + * tests for functions declared within the test file + * + */ + + +test('test a null coordinates in ECPointCompress', () => { + const x = null; + const y = null; + expect(() => { + ECPointCompress(x,y); + }).toThrowError('input cannot be null or undefined.'); +}); + +test('test a undefined coordinates in ECPointCompress', () => { + const x = undefined; + const y = undefined; + expect(() => { + ECPointCompress(x,y); + }).toThrowError('input cannot be null or undefined.'); +}); + +test('test null in pubKeyHexToUint8Array', () => { + const inputPublicKeyHex = null; + expect(() => { + pubKeyHexToUint8Array(inputPublicKeyHex); + }).toThrowError('input cannot be null or undefined.'); +}); + +test('test undefined in pubKeyHexToUint8Array', () => { + const inputPublicKeyHex = undefined; + expect(() => { + pubKeyHexToUint8Array(inputPublicKeyHex); + }).toThrowError('input cannot be null or undefined.'); +}); + +test('test an empty string in pubKeyHexToUint8Array', () => { + const inputPublicKeyHex = '' + const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); + expect(publicKey_u8a).toBeDefined(); + expect(publicKey_u8a).not.toBeNull(); + // removed because jest gives::: Received: serializes to the same string + // expect(publicKey_u8a).toEqual([]) +}); + +test('test compresedKeyInHex with an empty string', () => { + const inputPublicKeyHex = ''; + const compressedKey = compresedKeyInHex(inputPublicKeyHex); + expect(compressedKey).toBeDefined(); + expect(compressedKey).not.toBeNull(); +}); + +test('test compresedKeyInHex with null', () => { + const inputPublicKeyHex = null; + expect(() => { + compresedKeyInHex(inputPublicKeyHex); + }).toThrowError('input cannot be null or undefined.'); +}); + +test('test compresedKeyInHex with undefined', () => { + const inputPublicKeyHex = undefined; + expect(() => { + compresedKeyInHex(inputPublicKeyHex); + }).toThrowError('input cannot be null or undefined.'); +}); + +//**** end of tests for functions withing the test file + +// Common functions used for tests. Eliminate these when the key-did-provider is written. + +// write a separate test for this function... +// source: https://stackoverflow.com/questions/17171542/algorithm-for-elliptic-curve-point-compression +function ECPointCompress( x: Uint8Array, y: Uint8Array ) +{ + + if(x == null || y == null) { + throw new TypeError('input cannot be null or undefined.'); + } + + const out = new Uint8Array( x.length + 1 ); + + out[0] = 2 + ( y[ y.length-1 ] & 1 ); + out.set( x, 1 ); + + return out; +} + +function pubKeyHexToUint8Array(publicKeyHex: string) { + if(publicKeyHex == null) { + throw new TypeError('input cannot be null or undefined.'); + } + if(publicKeyHex.length % 2 == 0) { + return u8a.fromString(publicKeyHex,'base16'); + } else { + return u8a.fromString(('0'+publicKeyHex),'base16'); + } +} + +function compresedKeyInHex(publicKeyHex: string) { + if(publicKeyHex == null) { + throw new TypeError('input cannot be null or undefined.'); + } + const xHex = publicKeyHex.slice(0,publicKeyHex.length/2); + const yHex = publicKeyHex.slice(publicKeyHex.length/2,publicKeyHex.length); + + const xOctet = u8a.fromString(xHex,'base16') + const yOctet = u8a.fromString(yHex,'base16'); + + const compressedPoint = ECPointCompress( xOctet , yOctet ); + const compressedPointHex = u8a.toString(compressedPoint,'base16'); + return compressedPointHex; +} diff --git a/packages/key-did-resolver/src/__tests__/secp256r1.test.ts b/packages/key-did-resolver/src/__tests__/secp256r1.test.ts index 9ec6f21a04..ad235c54db 100644 --- a/packages/key-did-resolver/src/__tests__/secp256r1.test.ts +++ b/packages/key-did-resolver/src/__tests__/secp256r1.test.ts @@ -7,8 +7,7 @@ import * as u8a from 'uint8arrays' describe('Secp256r1 mapper', () => { - // testing the key from the did:key from the raw public key - it('successfully resolves the document from did', async () => { + it('successfully resolves the document from did:key from raw public key', async () => { const id = "zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ" const multicodecPubKey = multibase.decode(id) @@ -18,9 +17,8 @@ describe('Secp256r1 mapper', () => { expect(doc).toMatchSnapshot() }) - // testing the key from the did:key from the compressed public key - it('successfully resolves the document from did', async () => { - const id = "zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu" + it('successfully resolves the document from did:key from raw public key #2', async () => { + const id = "zrusAFgBbf84b8mBz8Cmy8UoFWKV52EaeRnK86vnLo4Z5QoRypE6hXVPN2urevZMAMtcTaCDFLWBaE1Q3jmdb1FHgve" const multicodecPubKey = multibase.decode(id) varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well @@ -28,80 +26,58 @@ describe('Secp256r1 mapper', () => { const doc = await mapper.keyToDidDoc(pubKeyBytes, id) expect(doc).toMatchSnapshot() }) - - // testing the key from the did:key from the uncompressed public key - it('successfully resolves the document from did', async () => { - const id = "z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY" + + it('successfully resolves the document from did:key from raw public key #3', async () => { + const id = "zrurwcJZss4ruepVNu1H3xmSirvNbzgBk9qrCktB6kaewXnJAhYWwtP3bxACqBpzjZdN7TyHNzzGGSSH5qvZsSDir9z" const multicodecPubKey = multibase.decode(id) varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) const doc = await mapper.keyToDidDoc(pubKeyBytes, id) expect(doc).toMatchSnapshot() - }) - -}) + }) -test('test a hex string with unexpected input', () => { - const inputPublicKeyHex = ''; - const publicKey_u8a = mapper.testHexString(inputPublicKeyHex); - expect(publicKey_u8a).toEqual(false); -}); - -test('test a hex string with unexpected input : try 2', () => { - const inputPublicKeyHex = 99; - const publicKey_u8a = mapper.testHexString(inputPublicKeyHex); - expect(publicKey_u8a).toEqual(false); -}); + it('successfully resolves the document from did:key from compressed public key', async () => { + const id = "zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu" -test('test a hex string shorter than 33 bytes', () => { - const inputPublicKeyHex = 'abc09'; - const publicKey_u8a = mapper.testHexString(inputPublicKeyHex); - expect(publicKey_u8a).toEqual(true); -}); + const multicodecPubKey = multibase.decode(id) + varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well + const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) + const doc = await mapper.keyToDidDoc(pubKeyBytes, id) + expect(doc).toMatchSnapshot() + }) -test('test testUint8Array with correct input', () => { - const inputCompressedPoint = Uint8Array.from([3,127,35,88,48,221,61,239,167,34,239,26,162,73,214,160,221,187,164,249,144,176,129,117,56,147,63,87,54,64,101,53,66]); - const publicKey_u8a = mapper.testUint8Array(inputCompressedPoint); - expect(publicKey_u8a).toEqual(true); -}); + it('successfully resolves the document from did:key from compressed public key #2', async () => { + const id = "zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv" -test('test testUint8Array with number', () => { - const inputCompressedPoint = 5; - const publicKey_u8a = mapper.testUint8Array(inputCompressedPoint); - expect(publicKey_u8a).toEqual(false); -}); + const multicodecPubKey = multibase.decode(id) + varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well + const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) + const doc = await mapper.keyToDidDoc(pubKeyBytes, id) + expect(doc).toMatchSnapshot() + }) -test('test testUint8Array with number', () => { - const inputCompressedPoint = 'donkey'; - const publicKey_u8a = mapper.testUint8Array(inputCompressedPoint); - expect(publicKey_u8a).toEqual(false); -}); + it('successfully resolves the document from did:key from compressed public key #3', async () => { + const id = "zDnaerDaTF5BXEavCrfRZEk316dpbLsfPDZ3WJ5hRTPFU2169" -test('expect pubKeyBytesToHex to throw an error for null', () => { - expect(() => { - mapper.pubKeyBytesToHex(null); - }).toThrowError('input must be a Uint8Array'); -}); - -test('expect pubKeyBytesToHex to throw an error for undefined', () => { - expect(() => { - mapper.pubKeyBytesToHex(); - }).toThrowError('input must be a Uint8Array'); -}); + const multicodecPubKey = multibase.decode(id) + varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well + const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) + const doc = await mapper.keyToDidDoc(pubKeyBytes, id) + expect(doc).toMatchSnapshot() + }) -test('expect pubKeyBytesToHex to throw an error for an unexpected integer', () => { - expect(() => { - mapper.pubKeyBytesToHex(5); - }).toThrowError('input must be a Uint8Array'); -}); + it('successfully resolves the document from did:key from uncompressed public key', async () => { + const id = "z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY" -test('expect pubKeyBytesToHex to throw an error for an unexpected object', () => { - expect(() => { - mapper.pubKeyBytesToHex({x: 6n, y: 5n}); - }).toThrowError('input must be a Uint8Array'); -}); + const multicodecPubKey = multibase.decode(id) + varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well + const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) + const doc = await mapper.keyToDidDoc(pubKeyBytes, id) + expect(doc).toMatchSnapshot() + }) +}) test('expect ECPointDecompress to throw an error for undefined', () => { expect(() => { @@ -121,81 +97,6 @@ test('expect ECPointDecompress to throw an error for unexpected input', () => { }).toThrowError('input must be a Uint8Array'); }); -test('expect publicKeyIntToXY to throw an error for incorrect type', () => { - expect(() => { - mapper.publicKeyIntToXY(5); - }).toThrowError('Input must be an object with properties x and y'); -}); - -test('expect publicKeyIntToXY to throw an error for {x: null, y: null}', () => { - expect(() => { - mapper.publicKeyIntToXY({x: null, y: null}); - }).toThrowError('Input coordinates must be BigInt'); -}); - -test('expect publicKeyIntToXY to throw an error for {x: undefined, y: undefined}', () => { - expect(() => { - mapper.publicKeyIntToXY(); - }).toThrow(); -}); - - -test('expect publicKeyHextToUint8ArrayPointPair to throw an error for {x: undefined, y: undefined}', () => { - expect(() => { - mapper.publicKeyHexToUint8ArrayPointPair(); - }).toThrowError('input must be string with characters 0-9,A-F,a-f'); -}); - - -test('expect publicKeyHexToUint8ArrayPointPair to throw an error for incorrect type', () => { - expect(() => { - mapper.publicKeyHexToUint8ArrayPointPair(5); - }).toThrowError('input must be string with characters 0-9,A-F,a-f'); -}); - - -test('expect publicKeyHexToUint8ArrayPointPair to throw an error for {x: null, y: null}', () => { - expect(() => { - mapper.publicKeyHexToUint8ArrayPointPair({x: null, y: null}); - }).toThrowError('input must be string with characters 0-9,A-F,a-f'); -}); - -test('expect publicKeyHexToUint8ArrayPointPair to throw an error for {x: undefined, y: undefined}', () => { - expect(() => { - mapper.publicKeyHexToUint8ArrayPointPair({x: undefined, y: undefined}); - }).toThrowError('input must be string with characters 0-9,A-F,a-f'); -}); - -test('expect publicKeyHexToUint8ArrayPointPair to throw an error for null', () => { - expect(() => { - mapper.publicKeyHexToUint8ArrayPointPair(null); - }).toThrowError('input must be string with characters 0-9,A-F,a-f'); -}); - -test('expect publicKeyToXY to throw an error for null', () => { - expect(() => { - mapper.publicKeyToXY(null); - }).toThrowError('input must be string with characters 0-9,A-F,a-f'); -}); - -test('expect publicKeyToXY to throw an error for undefined', () => { - expect(() => { - mapper.publicKeyToXY(); - }).toThrowError('input must be string with characters 0-9,A-F,a-f'); -}); - -test('expect publicKeyToXY to throw an error for a non string', () => { - expect(() => { - mapper.publicKeyToXY(5); - }).toThrowError('input must be string with characters 0-9,A-F,a-f'); -}); - -test('expect publicKeyToXY to throw an error for an invalid hex string', () => { - expect(() => { - mapper.publicKeyToXY('095ty'); - }).toThrowError('input must be string with characters 0-9,A-F,a-f'); -}); - test('expect publicKeyBytesToXY to throw an error for undefined', () => { expect(() => { mapper.pubKeyBytesToXY(); @@ -214,26 +115,6 @@ test('expect publicKeyBytesToXY to throw an error for and integer input', () => }).toThrowError('input must be a Uint8Array'); }); -test('empty key string to should not evaluate to null, or should it??', () => { - const inputPublicKeyHex = ''; - expect(() => { - mapper.publicKeyHexToUint8ArrayPointPair(inputPublicKeyHex); - }).toThrowError('input must be string with characters 0-9,A-F,a-f'); - }); - -test('test a hex string shorter than 33 bytes', () => { - const inputPublicKeyHex = '36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb6' - const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); - expect(publicKey_u8a).not.toEqual(null); -}); - -test('test a compressed public key in hex with an odd number of characters', () => { - const inputPublicKeyHex = '2f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb6'; - const output = Uint8Array.from([2,249,195,111,137,100,98,51,120,189,192,104,212,188,224,126,209,124,143,164,134,249,172,12,38,19,202,60,140,48, 109, 123, 182]); - const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); - expect(publicKey_u8a).toEqual(output); -}); - test('test a uncompressed public key in hex to an x,y point with x, and y url encoded with an unsupported prefix', () => { const inputPublicKeyHex = '03f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb61cd36717b8ac5e4fea8ad23dc8d0783c2318ee4ad7a80db6e0026ad0b072a24f' const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); @@ -247,7 +128,7 @@ test('test a compressed public key in hex to an x,y point with x, and y url enco const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); expect(() => { mapper.pubKeyBytesToXY(publicKey_u8a); - }).toThrowError('Unexpected pubKeyBytes'); + }).toThrowError('Unexpected pubKeyBytes'); }); test('test a compressed public key in hex to an x,y point with x, and y url encoded with an unsupported prefixi: try3', () => { @@ -293,10 +174,10 @@ test('test a hex string longer than 65 bytes: try2', () => { test('test a compressed public key in hex to an x,y point with x, and y url encoded', () => { const inputPublicKeyHex = '03f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb6' const output = { - xm: 'u-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y', - ym: 'uHNNnF7isXk_qitI9yNB4PCMY7krXqA224AJq0LByok8' + xm: '-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y', + ym: 'HNNnF7isXk_qitI9yNB4PCMY7krXqA224AJq0LByok8' }; - const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); + const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); const pubKeyBytesToXY = mapper.pubKeyBytesToXY(publicKey_u8a); expect(pubKeyBytesToXY).toEqual(output); }); @@ -304,9 +185,9 @@ test('test a compressed public key in hex to an x,y point with x, and y url enco test('test a uncompressed public key in hex to an x,y point with x, and y url encoded', () => { const inputPublicKeyHex = '04f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb61cd36717b8ac5e4fea8ad23dc8d0783c2318ee4ad7a80db6e0026ad0b072a24f' const output = { - xm: 'u-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y', - ym: 'uHNNnF7isXk_qitI9yNB4PCMY7krXqA224AJq0LByok8' - }; + xm: '-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y', + ym: 'HNNnF7isXk_qitI9yNB4PCMY7krXqA224AJq0LByok8' + }; const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); const pubKeyBytesToXY = mapper.pubKeyBytesToXY(publicKey_u8a); expect(pubKeyBytesToXY).toEqual(output); @@ -315,119 +196,14 @@ test('test a uncompressed public key in hex to an x,y point with x, and y url en test('test a raw public key in hex to an x,y point with x, and y url encoded', () => { const inputPublicKeyHex = 'f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb61cd36717b8ac5e4fea8ad23dc8d0783c2318ee4ad7a80db6e0026ad0b072a24f' const output = { - xm: 'u-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y', - ym: 'uHNNnF7isXk_qitI9yNB4PCMY7krXqA224AJq0LByok8' - }; + xm: '-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y', + ym: 'HNNnF7isXk_qitI9yNB4PCMY7krXqA224AJq0LByok8' + }; const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); const pubKeyBytesToXY = mapper.pubKeyBytesToXY(publicKey_u8a); - expect(pubKeyBytesToXY).toEqual(output); -}); - -test('convert a public key x,y where x and y are integers to an x,y point with x and y base64url encoded', () => { - const ecpoint = { - x: 112971204272793929541699765384018665134067875121047561926148644683187420494774n, - y: 13038276010400560657327464707708345466200402936352359974176190171319880557135n - }; - const output = { - xm: 'u-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y', - ym: 'uHNNnF7isXk_qitI9yNB4PCMY7krXqA224AJq0LByok8' - }; - - const base64urlPoint = mapper.publicKeyIntToXY(ecpoint); - expect(base64urlPoint).toEqual(output); - -}); - - -test('convert raw public key as a hex string into an x,y point with x and y base64url encoded', () => { - const inputPublicKeyHex = 'f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb61cd36717b8ac5e4fea8ad23dc8d0783c2318ee4ad7a80db6e0026ad0b072a24f' - const output = { - xm: 'u-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y', - ym: 'uHNNnF7isXk_qitI9yNB4PCMY7krXqA224AJq0LByok8' - }; - const base64urlPoint = mapper.publicKeyToXY(inputPublicKeyHex); - expect(base64urlPoint).toEqual(output); -}); - -test('expect publicKeyIntToXY to throw an error for incorrect type', () => { - expect(() => { - mapper.publicKeyIntToXY(5); - }).toThrowError('Input must be an object with properties x and y'); -}); - -test('expect publicKeyIntToXY to throw an error for {x: null, y: null}', () => { - expect(() => { - mapper.publicKeyIntToXY({x: null, y: null}); - }).toThrowError('Input coordinates must be BigInt'); -}); - -test('expect publicKeyIntToXY to have properties x and y', () => { - expect(() => { - mapper.publicKeyIntToXY({x: 5n, z: 8n}); - }).toThrowError('Input must have properties x and y'); -}); - -test('expect publicKeyIntToXY to throw an error for {x: undefined, y: undefined}', () => { - expect(() => { - mapper.publicKeyIntToXY(); - }).toThrowError('input cannot be null or undefined.'); -}); - -test('expect publicKeyIntToUint8ArrayPointPair to throw an error for {x: undefined, y: undefined}', () => { - expect(() => { - mapper.publicKeyHexToUint8ArrayPointPair(); - }).toThrowError('input must be string with characters 0-9,A-F,a-f'); -}); - -test('expect publicKeyIntToUint8ArrayPointPair to throw an error for {x: 5, y: 9}', () => { - expect(() => { - mapper.publicKeyIntToUint8ArrayPointPair({x: 5,y: 9}); - }).toThrowError('Input coordinates must be BigInt'); -}); - -test('expect publicKeyIntToUint8ArrayPointPair to throw an error for null', () => { - expect(() => { - mapper.publicKeyIntToUint8ArrayPointPair(null); - }).toThrowError('input cannot be null or undefined.'); -}); - -test('expect publicKeyIntToUint8ArrayPointPair to throw an error for mislabled coordinate properties', () => { - expect(() => { - mapper.publicKeyIntToUint8ArrayPointPair({x: 5n, z: 7n}); - }).toThrowError('Input must have properties x and y'); -}); - -test('expect publicKeyIntToUint8ArrayPointPair to throw an error for a non object', () => { - expect(() => { - mapper.publicKeyIntToUint8ArrayPointPair(6); - }).toThrowError('Input must be an object with properties x and y'); -}); - -test('convert a public key x,y where x and y are integers to a pair of Uint8Arrays', () => { - const ecpoint = { - x: 112971204272793929541699765384018665134067875121047561926148644683187420494774n, - y: 13038276010400560657327464707708345466200402936352359974176190171319880557135n - }; - const output = { xOctet : Uint8Array.from([ - 249, 195, 111, 137, 100, 98, 51, - 120, 189, 192, 104, 212, 188, 224, - 126, 209, 124, 143, 164, 134, 249, - 172, 12, 38, 19, 202, 60, 140, - 48, 109, 123, 182 - ] ) , - yOctet : Uint8Array.from([ - 28, 211, 103, 23, 184, 172, 94, 79, - 234, 138, 210, 61, 200, 208, 120, 60, - 35, 24, 238, 74, 215, 168, 13, 182, - 224, 2, 106, 208, 176, 114, 162, 79 - ] ) - }; - - const u8aPoint = mapper.publicKeyIntToUint8ArrayPointPair(ecpoint); - expect(u8aPoint).toEqual(output); + expect(pubKeyBytesToXY).toEqual(output); }); - test('test a compressed public key in hex to an x,y point as BigInt (with the wrong parity)', () => { const inputPublicKeyHex = '02f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb6'; const output = { @@ -452,42 +228,6 @@ test('key decompression (y-coordinate even)', () => { expect(point).toEqual(output); }); -test('key compression (y-coordinate even)', () => { - // inputPublicKeyHex derived from: https://stackoverflow.com/questions/67135136/unable-to-verify-a-raw-uint8array-ecdsa-secp256r1-message-signature-pubkey-usi - - const inputPublicKeyHex = '39c3dd74131729446dc1b3da67d49fc046fcbf072fcc5b9fa51c05b974307f969c403b1635f0449f02bd422751e33121a4434f152f2b2b2a3f675219c5d925f6' - const output = Uint8Array.from([2,57,195,221,116,19,23,41,68,109,193,179,218,103,212,159,192,70,252,191,7,47,204,91,159,165,28,5,185,116,48,127,150]); - - const u8aPoint = mapper.publicKeyHexToUint8ArrayPointPair(inputPublicKeyHex); - const compressedPoint = ECPointCompress(u8aPoint.xOctet, u8aPoint.yOctet); - - expect(compressedPoint).toEqual(output); - -}); - -test('key decompression (y-coordinate odd) key#2', () => { - - const inputCompressedPoint = Uint8Array.from([3,127,35,88,48,221,61,239,167,34,239,26,162,73,214,160,221,187,164,249,144,176,129,117,56,147,63,87,54,64,101,53,66]); - const output = { - x: 57506180088397527878367021711159096752486239922681589595989108987041675556162n, - y: 60351358491784072971514173700673656664870632871947100762396585099496243621173n - }; - - const point = mapper.ECPointDecompress( inputCompressedPoint ) - - expect(point).toEqual(output); -}); - -test('key compression (y-coordinate odd) key#2', () => { - const inputPublicKeyHex = '7f235830dd3defa722ef1aa249d6a0ddbba4f990b0817538933f573640653542856da88d335f1fb25b8bcfbe089528dce09b1f7cb99fdd60f88300f4c2cc6d35' - const output = Uint8Array.from([3,127,35,88,48,221,61,239,167,34,239,26,162,73,214,160,221,187,164,249,144,176,129,117,56,147,63,87,54,64,101,53,66]); - - const u8aPoint = mapper.publicKeyHexToUint8ArrayPointPair(inputPublicKeyHex); - const compressedPoint = ECPointCompress(u8aPoint.xOctet, u8aPoint.yOctet); - - expect(compressedPoint).toEqual(output); -}); - test('key decompression (y-coordinate odd)', () => { const inputCompressedPoint = Uint8Array.from([3,249,195,111,137,100,98,51,120,189,192,104,212,188,224,126,209,124,143,164,134,249,172,12,38,19,202,60,140,48,109,123,182]); @@ -501,158 +241,29 @@ test('key decompression (y-coordinate odd)', () => { expect(point).toEqual(output); }); -test('key compression (y-coordinate odd)', () => { - const inputPublicKeyHex = 'f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb61cd36717b8ac5e4fea8ad23dc8d0783c2318ee4ad7a80db6e0026ad0b072a24f' - const output = Uint8Array.from([3,249,195,111,137,100,98,51,120,189,192,104,212,188,224,126,209,124,143,164,134,249,172,12,38,19,202,60,140,48,109,123,182]); - - const u8aPoint = mapper.publicKeyHexToUint8ArrayPointPair(inputPublicKeyHex); - const compressedPoint = ECPointCompress(u8aPoint.xOctet, u8aPoint.yOctet); - - expect(compressedPoint).toEqual(output); -}); - -test('raw public key as hex string to x,y point with x and y as uint8Arrays', () => { - const inputPublicKeyHex = 'f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb61cd36717b8ac5e4fea8ad23dc8d0783c2318ee4ad7a80db6e0026ad0b072a24f' - const output = { xOctet : Uint8Array.from([ - 249, 195, 111, 137, 100, 98, 51, - 120, 189, 192, 104, 212, 188, 224, - 126, 209, 124, 143, 164, 134, 249, - 172, 12, 38, 19, 202, 60, 140, - 48, 109, 123, 182 - ] ) , - yOctet : Uint8Array.from([ - 28, 211, 103, 23, 184, 172, 94, 79, - 234, 138, 210, 61, 200, 208, 120, 60, - 35, 24, 238, 74, 215, 168, 13, 182, - 224, 2, 106, 208, 176, 114, 162, 79 - ] ) - }; - - const u8aPoint = mapper.publicKeyHexToUint8ArrayPointPair(inputPublicKeyHex); - expect(u8aPoint).toEqual(output); -}); - -test('show how to compress a raw public key in hex and return a compressed key in hex', () => { - const inputPublicKeyHex = 'f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb61cd36717b8ac5e4fea8ad23dc8d0783c2318ee4ad7a80db6e0026ad0b072a24f'; - const output = '03f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb6'; - const compresedKey = compresedKeyInHex(inputPublicKeyHex); - expect(compresedKey).toEqual(output); -}); - -test('show how to convert a raw public key in hex and return an uncompressed key in hex', () => { - const inputPublicKeyHex = 'f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb61cd36717b8ac5e4fea8ad23dc8d0783c2318ee4ad7a80db6e0026ad0b072a24f'; - const output = '04f9c36f8964623378bdc068d4bce07ed17c8fa486f9ac0c2613ca3c8c306d7bb61cd36717b8ac5e4fea8ad23dc8d0783c2318ee4ad7a80db6e0026ad0b072a24f'; - const uncompressedKey = '04'+ inputPublicKeyHex; - expect(uncompressedKey).toEqual(output); -}); - -/* - * tests for functions declared within the test file - * - */ - - -test('test a null coordinates in ECPointCompress', () => { - const x = null; - const y = null; - expect(() => { - ECPointCompress(x,y); - }).toThrowError('input cannot be null or undefined.'); -}); - -test('test a undefined coordinates in ECPointCompress', () => { - const x = undefined; - const y = undefined; - expect(() => { - ECPointCompress(x,y); - }).toThrowError('input cannot be null or undefined.'); -}); - -test('test null in pubKeyHexToUint8Array', () => { - const inputPublicKeyHex = null; - expect(() => { - pubKeyHexToUint8Array(inputPublicKeyHex); - }).toThrowError('input cannot be null or undefined.'); -}); - -test('test undefined in pubKeyHexToUint8Array', () => { - const inputPublicKeyHex = undefined; - expect(() => { - pubKeyHexToUint8Array(inputPublicKeyHex); - }).toThrowError('input cannot be null or undefined.'); -}); - -test('test an empty string in pubKeyHexToUint8Array', () => { - const inputPublicKeyHex = '' - const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); - expect(publicKey_u8a).toBeDefined(); - expect(publicKey_u8a).not.toBeNull(); - // removed because jest gives::: Received: serializes to the same string - // expect(publicKey_u8a).toEqual([]) -}); +test('key decompression (y-coordinate odd) key#2', () => { -test('test compresedKeyInHex with an empty string', () => { - const inputPublicKeyHex = ''; - const compressedKey = compresedKeyInHex(inputPublicKeyHex); - expect(compressedKey).toBeDefined(); - expect(compressedKey).not.toBeNull(); -}); + const inputCompressedPoint = Uint8Array.from([3,127,35,88,48,221,61,239,167,34,239,26,162,73,214,160,221,187,164,249,144,176,129,117,56,147,63,87,54,64,101,53,66]); + const output = { + x: 57506180088397527878367021711159096752486239922681589595989108987041675556162n, + y: 60351358491784072971514173700673656664870632871947100762396585099496243621173n + }; -test('test compresedKeyInHex with null', () => { - const inputPublicKeyHex = null; - expect(() => { - compresedKeyInHex(inputPublicKeyHex); - }).toThrowError('input cannot be null or undefined.'); -}); + const point = mapper.ECPointDecompress( inputCompressedPoint ) -test('test compresedKeyInHex with undefined', () => { - const inputPublicKeyHex = undefined; - expect(() => { - compresedKeyInHex(inputPublicKeyHex); - }).toThrowError('input cannot be null or undefined.'); + expect(point).toEqual(output); }); +//**** end of tests -//**** end of tests for functions withing the test file - -// write a separate test for this function... -// source: https://stackoverflow.com/questions/17171542/algorithm-for-elliptic-curve-point-compression -function ECPointCompress( x: Uint8Array, y: Uint8Array ) -{ - - if(x == null || y == null) { - throw new TypeError('input cannot be null or undefined.'); - } - - const out = new Uint8Array( x.length + 1 ); - - out[0] = 2 + ( y[ y.length-1 ] & 1 ); - out.set( x, 1 ); - - return out; -} +// Function for test. Eliminate this when key-did-resolver is written. function pubKeyHexToUint8Array(publicKeyHex: string) { if(publicKeyHex == null) { throw new TypeError('input cannot be null or undefined.'); } if(publicKeyHex.length % 2 == 0) { - return u8a.fromString(publicKeyHex,'base16'); + return u8a.fromString(publicKeyHex,'base16'); } else { return u8a.fromString(('0'+publicKeyHex),'base16'); } } - -function compresedKeyInHex(publicKeyHex: string) { - if(publicKeyHex == null) { - throw new TypeError('input cannot be null or undefined.'); - } - const xHex = publicKeyHex.slice(0,publicKeyHex.length/2); - const yHex = publicKeyHex.slice(publicKeyHex.length/2,publicKeyHex.length); - - const xOctet = u8a.fromString(xHex,'base16') - const yOctet = u8a.fromString(yHex,'base16'); - - const compressedPoint = ECPointCompress( xOctet , yOctet ); - const compressedPointHex = u8a.toString(compressedPoint,'base16'); - return compressedPointHex; -} diff --git a/packages/key-did-resolver/src/__tests__/secp384r1.test.ts b/packages/key-did-resolver/src/__tests__/secp384r1.test.ts new file mode 100644 index 0000000000..c8acf15570 --- /dev/null +++ b/packages/key-did-resolver/src/__tests__/secp384r1.test.ts @@ -0,0 +1,292 @@ +// Brent Shambaugh . 2021. + +import varint from "varint" +import multibase from "multibase" +import * as mapper from "../secp384r1" +import * as u8a from 'uint8arrays' + +describe('Secp384r1 mapper', () => { + + it('Secp384r1 mapper successfully resolves the document from did:key from raw public key', async () => { + const id = "zFwfeyrSyWdksRYykTGGtagWazFB5zS4CjQcxDMQSNmCTQB5QMqokx2VJz4vBB2hN1nUrYDTuYq3kd1BM5cUCfFD4awiNuzEBuoy6rZZTMCsZsdvWkDXY6832qcAnzE7YGw43KU" + + const multicodecPubKey = multibase.decode(id) + varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well + const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) + const doc = await mapper.keyToDidDoc(pubKeyBytes, id) + expect(doc).toMatchSnapshot() + }) + + it('Secp384r1 mapper successfully resolves the document from did:key from raw public key #2', async () => { + const id = "zFwepbBSaPFjt5T1zWptHaXugLNxHYABfJrDoAZRYxKjNkpdfrniF3pvYQAXwxVB7afhmsgzYtSCzTVZQ3F5SPHzP5PuHgtBGNYucZTSrnA7yTTDr7WGQZaTTkJWfiH47jW5ahU" + + const multicodecPubKey = multibase.decode(id) + varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well + const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) + const doc = await mapper.keyToDidDoc(pubKeyBytes, id) + expect(doc).toMatchSnapshot() + }) + + it('Secp384r1 mapper successfully resolves the document from did:key from raw public key #3', async () => { + const id = "zFwfwzpxzCAUjJK6X7cLDFjxbp6G3iJy6AcntWLBu5SxJeGBjge7jVkmARyUqkJideMFofkhGF94wLopAmuqCH1JQ3fbzxmrBwKK52qF5w429kUJk5NdR8BJwDxpeWryV4oAH27"; + + const multicodecPubKey = multibase.decode(id) + varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well + const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) + const doc = await mapper.keyToDidDoc(pubKeyBytes, id) + expect(doc).toMatchSnapshot() + }) + + it('Secp384r1 mapper successfully resolves the document from did:key from compressed public key', async () => { + const id = "z82Lm1MpAkeJcix9K8TMiLd5NMAhnwkjjCBeWHXyu3U4oT2MVJJKXkcVBgjGhnLBn2Kaau9" + + const multicodecPubKey = multibase.decode(id) + varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well + const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) + const doc = await mapper.keyToDidDoc(pubKeyBytes, id) + expect(doc).toMatchSnapshot() + }) + + it('Secp384r1 mapper successfully resolves the document from did:key from compressed public key #2', async () => { + const id = "z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54" + + const multicodecPubKey = multibase.decode(id) + varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well + const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) + const doc = await mapper.keyToDidDoc(pubKeyBytes, id) + expect(doc).toMatchSnapshot() + }) + + it('Secp384r1 mapper successfully resolves the document from did:key from compressed public key #3', async () => { + const id = "z82Lm2BuneDPATu4BSWzhZwuandHAwY4DJrv3gAbo8RvG6yBTLJx6AhgoSmKy8XSK4HaPvA" + + const multicodecPubKey = multibase.decode(id) + varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well + const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) + const doc = await mapper.keyToDidDoc(pubKeyBytes, id) + expect(doc).toMatchSnapshot() + }) + + // testing the key from the did:key from the uncompressed public key + it('successfully resolves the document from did', async () => { + const id = "z28xDr9xiQCrXbooH2aC3eMVv74QKvxBgP1DHCMBWz6CvTHmdt4rtsH9JSHGsyPzdQpfMBJSSAHFh1zTjiyLhKchrMnNfBVEtCziwX2yy3YiQY9t6WcVUpSdVHaxeRz5x6JYoGGPJ" + + const multicodecPubKey = multibase.decode(id) + varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well + const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) + const doc = await mapper.keyToDidDoc(pubKeyBytes, id) + expect(doc).toMatchSnapshot() + }) + + // testing the key from the did:key from the uncompressed public key + it('successfully resolves the document from did', async () => { + const id = "z28xDrNf4RYwmuLQmfFBWWwiaxZtqyfME8BGUHemrsKUn6ShdzCLZWq2ZhmmSpVK2rtSLoeA1CJjrwGjZ64yCjJ9odVTYDdAMSu2LsTL1c5ehyQdkatFonfv3d7VNCByDrqntBoVz"; + + const multicodecPubKey = multibase.decode(id) + varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well + const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) + const doc = await mapper.keyToDidDoc(pubKeyBytes, id) + expect(doc).toMatchSnapshot() + }) + + + +}) + +test('expect ECPointDecompress to throw an error for undefined', () => { + expect(() => { + mapper.ECPointDecompress(); + }).toThrowError('input must be a Uint8Array'); +}); + +test('expect ECPointDecompress to throw an error for null', () => { + expect(() => { + mapper.ECPointDecompress(null); + }).toThrowError('input must be a Uint8Array'); +}); + +test('expect ECPointDecompress to throw an error for unexpected input', () => { + expect(() => { + mapper.ECPointDecompress(5); + }).toThrowError('input must be a Uint8Array'); +}); + +test('expect publicKeyBytesToXY to throw an error for undefined', () => { + expect(() => { + mapper.pubKeyBytesToXY(); + }).toThrowError('input must be a Uint8Array'); +}); + +test('expect publicKeyBytesToXY to throw an error for null', () => { + expect(() => { + mapper.pubKeyBytesToXY(null); + }).toThrowError('input must be a Uint8Array'); +}); + +test('expect publicKeyBytesToXY to throw an error for and integer input', () => { + expect(() => { + mapper.pubKeyBytesToXY(5); + }).toThrowError('input must be a Uint8Array'); +}); + +test('test a uncompressed public key in hex to an x,y point with x, and y url with an unsupported prefix', () => { + const inputPublicKeyHex = '05041d73367caac24ba6ef7a2cc6b32cb525ef806dbf4a9044507863fbc2e441ad9425f17021104e76637f844db9aec27168d967d6543947d9fbdb82021b9942a0a9f0e48cfd6075e69ae3674f6724368e42561bf73dbf107a0ed17e92858aa36f'; + const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); + expect(() => { + mapper.pubKeyBytesToXY(publicKey_u8a); + }).toThrowError('Unexpected pubKeyBytes'); +}); + +test('test a uncompressed public key in hex to an x,y point with x, and y url encoded with an unsupported prefix that is too long', () => { + const inputPublicKeyHex = '03041d73367caac24ba6ef7a2cc6b32cb525ef806dbf4a9044507863fbc2e441ad9425f17021104e76637f844db9aec27168d967d6543947d9fbdb82021b9942a0a9f0e48cfd6075e69ae3674f6724368e42561bf73dbf107a0ed17e92858aa36f07'; + const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); + expect(() => { + mapper.pubKeyBytesToXY(publicKey_u8a); + }).toThrowError('Unexpected pubKeyBytes'); +}); + +test('test a compressed public key in hex to an x,y point with x, and y url encoded with an unsupported prefixi: try2', () => { + const inputPublicKeyHex = '050e167184c0436f5940e63d89f3827bb90978cbd3b26ef66d52da7638ce0f83492fe3f27794d8dd75a8b9553161b8613a'; + const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); + expect(() => { + mapper.pubKeyBytesToXY(publicKey_u8a); + }).toThrowError('Unexpected pubKeyBytes'); +}); + +test('test a compressed public key in hex to an x,y point with x, and y url encoded with an unsupported prefixi: try3', () => { + const inputPublicKeyHex = '040e167184c0436f5940e63d89f3827bb90978cbd3b26ef66d52da7638ce0f83492fe3f27794d8dd75a8b9553161b8613a'; + const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); + expect(() => { + mapper.pubKeyBytesToXY(publicKey_u8a); + }).toThrowError('Unexpected pubKeyBytes'); +}); + +test('test a compressed public key in hex to an x,y point with x, and y url encoded with an unsupported prefix', () => { + const inputPublicKeyHex = '040e167184c0436f5940e63d89f3827bb90978cbd3b26ef66d52da7638ce0f83492fe3f27794d8dd75a8b9553161b8613a'; + const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); + expect(() => { + mapper.pubKeyBytesToXY(publicKey_u8a); + }).toThrowError('Unexpected pubKeyBytes'); +}); + +test('test a compressed public key in hex to an x,y point with x, and y url encoded with an unexpected length', () => { + const inputPublicKeyHex = '020e167184c0436f5940e63d89f3827bb90978cbd3b26ef66d52da7638ce0f83492fe3f27794d8dd75a8b9553161b8613a07'; + const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); + expect(() => { + mapper.pubKeyBytesToXY(publicKey_u8a); + }).toThrowError('Unexpected pubKeyBytes'); +}); + +test('test a hex string longer than 97 bytes', () => { + const inputPublicKeyHex = '0704041d73367caac24ba6ef7a2cc6b32cb525ef806dbf4a9044507863fbc2e441ad9425f17021104e76637f844db9aec27168d967d6543947d9fbdb82021b9942a0a9f0e48cfd6075e69ae3674f6724368e42561bf73dbf107a0ed17e92858aa36f'; + const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); + expect(() => { + mapper.pubKeyBytesToXY(publicKey_u8a); + }).toThrowError('Unexpected pubKeyBytes'); +}); + +test('test a hex string longer than 97 bytes: try2', () => { + const inputPublicKeyHex = '04041d73367caac24ba6ef7a2cc6b32cb525ef806dbf4a9044507863fbc2e441ad9425f17021104e76637f844db9aec27168d967d6543947d9fbdb82021b9942a0a9f0e48cfd6075e69ae3674f6724368e42561bf73dbf107a0ed17e92858aa36f07'; + const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); + expect(() => { + mapper.pubKeyBytesToXY(publicKey_u8a); + }).toThrowError('Unexpected pubKeyBytes'); +}) + +test('test a compressed public key in hex to an x,y point with x, and y url encoded', () => { + const inputPublicKeyHex = '020e167184c0436f5940e63d89f3827bb90978cbd3b26ef66d52da7638ce0f83492fe3f27794d8dd75a8b9553161b8613a'; + const output = { + xm: 'DhZxhMBDb1lA5j2J84J7uQl4y9OybvZtUtp2OM4Pg0kv4_J3lNjddai5VTFhuGE6', + ym: 'QAzuG_cfV32pd8adVMpKYk5x9a9ZA5DMntSKQjl46SaLEkRPs2_gWoIu0cCuY8cy' + }; + const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); + const pubKeyBytesToXY = mapper.pubKeyBytesToXY(publicKey_u8a); + expect(pubKeyBytesToXY).toEqual(output); +}); + +test('test a uncompressed public key in hex to an x,y point with x, and y url encoded', () => { + const inputPublicKeyHex = '04041d73367caac24ba6ef7a2cc6b32cb525ef806dbf4a9044507863fbc2e441ad9425f17021104e76637f844db9aec27168d967d6543947d9fbdb82021b9942a0a9f0e48cfd6075e69ae3674f6724368e42561bf73dbf107a0ed17e92858aa36f'; + const output = { + xm: 'BB1zNnyqwkum73osxrMstSXvgG2_SpBEUHhj-8LkQa2UJfFwIRBOdmN_hE25rsJx', + ym: 'aNln1lQ5R9n724ICG5lCoKnw5Iz9YHXmmuNnT2ckNo5CVhv3Pb8Qeg7RfpKFiqNv' + }; + const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); + const pubKeyBytesToXY = mapper.pubKeyBytesToXY(publicKey_u8a); + expect(pubKeyBytesToXY).toEqual(output); +}); + +test('test a raw public key in hex to an x,y point with x, and y url encoded', () => { + const inputPublicKeyHex = '041d73367caac24ba6ef7a2cc6b32cb525ef806dbf4a9044507863fbc2e441ad9425f17021104e76637f844db9aec27168d967d6543947d9fbdb82021b9942a0a9f0e48cfd6075e69ae3674f6724368e42561bf73dbf107a0ed17e92858aa36f'; + const output = { + xm: 'BB1zNnyqwkum73osxrMstSXvgG2_SpBEUHhj-8LkQa2UJfFwIRBOdmN_hE25rsJx', + ym: 'aNln1lQ5R9n724ICG5lCoKnw5Iz9YHXmmuNnT2ckNo5CVhv3Pb8Qeg7RfpKFiqNv' + }; + const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); + const pubKeyBytesToXY = mapper.pubKeyBytesToXY(publicKey_u8a); + expect(pubKeyBytesToXY).toEqual(output); +}); + +test('test a compressed public key in hex to an x,y point as BigInt', () => { + const inputPublicKeyHex = '0265a9eb600585a6ef6edbf4c4f7769bbadb3ffa721013ade91fd272fe30457888854f53b8c41598bddd28bb6fb637f971'; + const output = { + x: 15647482891880695628361423295295048383141137301636270605834221988066059282765781769641660206771257338747460454447473n, + y: 9546043628548965590572582485871225792872188688117717253140508546948981101702483600611360132547640944614267655802760n + }; + const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); + const point = mapper.ECPointDecompress(publicKey_u8a); + expect(point).toEqual(output); +}); + + +test('key decompression (y-coordinate even)', () => { + const inputCompressedPoint = Uint8Array.from([2, 35, 113, 197, 135, 41, 168, 153, 179, 78, 104, 37, 216, 27, 218, 187, 126, 99, 72, 18, 196, 175, 235, 162, 201, 186, 142, 10, 149, 170, 210, 194, 49, 95, 248, 223, 21, 242, 90, 255, 4, 44, 200, 42, 72, 183, 130, 241, 36]); + const output = { + x: 5455395577368722148202284288295229016372960408130441469301488141758433415923379298322689245302276505277663568654628n, + y: 2491330177551765948830201920923407579397228012261106122732934988988922617191325104752570464363844486817305467959018n + }; + + const point = mapper.ECPointDecompress( inputCompressedPoint ); + + expect(point).toEqual(output); +}); + +test('key decompression (y-coordinate odd)', () => { + + const inputCompressedPoint = Uint8Array.from([3, 85, 60, 88, 67, 106, 249, 139, 178, 116, 167, 2, 233, 109, 11, 235, 188, 203, 103, 93, 18, 204, 150, 41, 122, 192, 55, 55, 55, 99, 127, 81, 127, 209, 143, 40, 136, 37, 1, 46, 95, 243, 141, 178, 93, 39, 156, 202, 42]); + const output = { + x: 13118978274206463185421015920426680429096138428147576347133764307914667369844920909760800880755191326175781961124394n, + y: 17805753635780018091095764692198364444788931266580341460971181687466050846576932422297677291691773698932002655999591n + }; + + const point = mapper.ECPointDecompress( inputCompressedPoint ) + + expect(point).toEqual(output); +}); + +test('key decompression (y-coordinate odd) key#2', () => { + + const inputCompressedPoint = Uint8Array.from([ 3, 171, 37, 12, 72, 230, 28, 207, 37, 101, 156, 140, 69, 139, 233, 213, 25, 26, 99, 179, 80, 88, 236, 18, 49, 84, 35, 158, 171, 117, 128, 162, 150, 77, 208, 229, 89, 196, 110, 214, 41, 237, 36, 9, 182, 118, 204, 121, 43 ]); + + const output = { + x: 26341583073126796700418388682664298992635319922642610490472596881255947259679994775386951611010846056313433587743019n, + y: 36342522670550545791098022209848857466288485673789913258992953762740028300348932631529997025438540520232064962412623n + }; + + const point = mapper.ECPointDecompress( inputCompressedPoint ) + + expect(point).toEqual(output); +}); +//**** end of tests + +// Function for test. Eliminate this when key-did-resolver is written. + +function pubKeyHexToUint8Array(publicKeyHex: string) { + if(publicKeyHex == null) { + throw new TypeError('input cannot be null or undefined.'); + } + if(publicKeyHex.length % 2 == 0) { + return u8a.fromString(publicKeyHex,'base16'); + } else { + return u8a.fromString(('0'+publicKeyHex),'base16'); + } +} diff --git a/packages/key-did-resolver/src/__tests__/secp521r1.test.ts b/packages/key-did-resolver/src/__tests__/secp521r1.test.ts new file mode 100644 index 0000000000..45834c430f --- /dev/null +++ b/packages/key-did-resolver/src/__tests__/secp521r1.test.ts @@ -0,0 +1,176 @@ +// Brent Shambaugh . 2021. + +import varint from "varint" +import multibase from "multibase" +import * as mapper from "../secp521r1" +import * as u8a from 'uint8arrays' + +describe('Secp521r1 mapper', () => { + + // testing the key from the did:key from the compressed public key + it('successfully resolves the document from did', async () => { + const id = "z2J9gaYhkf4Ax2QA65KkcrSxr8JDSxUBwzFq3jmq5iBroY2tE7s1uohXVqEvALPxbvdzbWWQTtHvTprUdbNFha3HawyPcD9P" + + const multicodecPubKey = multibase.decode(id) + varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well + const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) + const doc = await mapper.keyToDidDoc(pubKeyBytes, id) + expect(doc).toMatchSnapshot() + }) + + // testing the key from the did:key from the compressed public key + it('successfully resolves the document from did', async () => { + const id = "z2J9gcGdbo8riFqfRzgo3gjJyFcbNJm75hrnpDrZTNqQQxgNVBTtKndBiKxzGXrAbyw5W88VDbR1B1FvRQNTnSezghqnJ7p6" + + const multicodecPubKey = multibase.decode(id) + varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well + const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) + const doc = await mapper.keyToDidDoc(pubKeyBytes, id) + expect(doc).toMatchSnapshot() + }) + + + // testing the key from the did:key from the compressed public key + it('successfully resolves the document from did', async () => { + const id = "z2J9gcGTjd3NaNifwmaNZN27xioMAzHHCDBmkuQ552hm9kWrzhUepDCSAhiuRYBj1sSXR1LBxgqh6vasYzc8JhC12FpaNDhT" + + const multicodecPubKey = multibase.decode(id) + varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well + const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) + const doc = await mapper.keyToDidDoc(pubKeyBytes, id) + expect(doc).toMatchSnapshot() + }) + +}) + +test('expect ECPointDecompress to throw an error for undefined', () => { + expect(() => { + mapper.ECPointDecompress(); + }).toThrowError('input must be a Uint8Array'); +}); + +test('expect ECPointDecompress to throw an error for null', () => { + expect(() => { + mapper.ECPointDecompress(null); + }).toThrowError('input must be a Uint8Array'); +}); + +test('expect ECPointDecompress to throw an error for unexpected input', () => { + expect(() => { + mapper.ECPointDecompress(5); + }).toThrowError('input must be a Uint8Array'); +}); + +test('expect publicKeyBytesToXY to throw an error for undefined', () => { + expect(() => { + mapper.pubKeyBytesToXY(); + }).toThrowError('input must be a Uint8Array'); +}); + +test('expect publicKeyBytesToXY to throw an error for null', () => { + expect(() => { + mapper.pubKeyBytesToXY(null); + }).toThrowError('input must be a Uint8Array'); +}); + +test('expect publicKeyBytesToXY to throw an error for and integer input', () => { + expect(() => { + mapper.pubKeyBytesToXY(5); + }).toThrowError('input must be a Uint8Array'); +}); + +test('test a compressed public key in hex to an x,y point with x, and y url encoded with an unsupported prefixi: try2', () => { + const inputPublicKeyHex = '050013673d87114741d183ee420e19472782c1c50a35794abad05d453246b5fd56c1bbb6baea58fa5a19e26586d4bc3db18ff91fac537cdf0913a204c5c6a9949cce8c'; + const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); + expect(() => { + mapper.pubKeyBytesToXY(publicKey_u8a); + }).toThrowError('Unexpected pubKeyBytes'); +}); + + +test('test a compressed public key in hex to an x,y point with x, and y url encoded with an unsupported prefixi: try3', () => { + const inputPublicKeyHex = '040024fd2216f69ad8a84a8ec630fa4879f82639795a83fa07769d134544130f3af5cfd86ff5460ee7e88a21115cfb9c91898c8ca492feca1992b35c23690af58bd112'; + const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); + expect(() => { + mapper.pubKeyBytesToXY(publicKey_u8a); + }).toThrowError('Unexpected pubKeyBytes'); +}); + +test('test a compressed public key in hex to an x,y point with x, and y url encoded with an unsupported prefix', () => { + const inputPublicKeyHex = '010024fd2216f69ad8a84a8ec630fa4879f82639795a83fa07769d134544130f3af5cfd86ff5460ee7e88a21115cfb9c91898c8ca492feca1992b35c23690af58bd112' + const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); + expect(() => { + mapper.pubKeyBytesToXY(publicKey_u8a); + }).toThrowError('Unexpected pubKeyBytes'); +}); + +test('test a compressed public key in hex to an x,y point with x, and y url encoded with an unexpected length', () => { + const inputPublicKeyHex = '030024fd2216f69ad8a84a8ec630fa4879f82639795a83fa07769d134544130f3af5cfd86ff5460ee7e88a21115cfb9c91898c8ca492feca19'; + const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); + expect(() => { + mapper.pubKeyBytesToXY(publicKey_u8a); + }).toThrowError('Unexpected pubKeyBytes'); +}); + +test('test a hex string longer than 67 bytes', () => { + const inputPublicKeyHex = '010024fd2216f69ad8a84a8ec630fa4879f82639795a83fa07769d134544130f3af5cfd86ff5460ee7e88a21115cfb9c91898c8ca492feca1992b35c23690af58bd112000' + const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); + expect(() => { + mapper.pubKeyBytesToXY(publicKey_u8a); + }).toThrowError('Unexpected pubKeyBytes'); +}); + + +test('test a hex string longer than 67 bytes: try2', () => { + const inputPublicKeyHex = '030024fd2216f69ad8a84a8ec630fa4879f82639795a83fa07769d134544130f3af5cfd86ff5460ee7e88a21115cfb9c91898c8ca492feca1992b35c23690af58bd11200'; + const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); + expect(() => { + mapper.pubKeyBytesToXY(publicKey_u8a); + }).toThrowError('Unexpected pubKeyBytes'); +}) + +test('test a compressed public key in hex to an x,y point with x, and y url encoded', () => { + const inputPublicKeyHex = '0300978fcb87684ebbfb723e695fa6e46640e05624f3e3be9e01c23f713088aa542a8006c259b6a8152f5991bf3713eada06b9eb30c0fcc5c9f877143e51d0c960f8e4'; + const output = { + xm: 'l4_Lh2hOu_tyPmlfpuRmQOBWJPPjvp4Bwj9xMIiqVCqABsJZtqgVL1mRvzcT6toGueswwPzFyfh3FD5R0Mlg-OQ', + ym: 'iV1Wy8VO05NKYylHjeXy7RL5zM2gG5pP8PIqBjbFXdo9MPZ3MsyyIF54Ykz76jFp55cD3CrynsUTD41JCQyFrJs' + }; + const publicKey_u8a = pubKeyHexToUint8Array(inputPublicKeyHex); + const pubKeyBytesToXY = mapper.pubKeyBytesToXY(publicKey_u8a); + expect(pubKeyBytesToXY).toEqual(output); +}); + +test('key decompression (y-coordinate even)', () => { + const inputCompressedPoint = Uint8Array.from([2,1,136,150,76,97,65,179,107,240,223,46,252,94,95,182,167,112,107,112,89,123,182,47,127,128,174,58,9,124,57,243,252,135,25,91,0,99,153,233,154,136,48,21,214,42,104,181,152,232,34,58,26,117,10,127,126,153,27,98,170,127,154,76,15,186,131]); + const output = { + x: 5263732472326197894199528512881258061258008985078293539314860591268612844870409579995212283440520259722240821760850735845522405972639427405605101549097302659n, + y: 1607355092586893166614735742487687197205018279836427959934123116181383543385248294164182350918606129115312468371462347169202332686725754242897081121013431644n + }; + const point = mapper.ECPointDecompress( inputCompressedPoint ); + expect(point).toEqual(output); +}); + +test('key decompression (y-coordinate odd)', () => { + const inputCompressedPoint = Uint8Array.from([3,0,151,143,203,135,104,78,187,251,114,62,105,95,166,228,102,64,224,86,36,243,227,190,158,1,194,63,113,48,136,170,84,42,128,6,194,89,182,168,21,47,89,145,191,55,19,234,218,6,185,235,48,192,252,197,201,248,119,20,62,81,208,201,96,248,228]); + const output = { + x: 2032110154488788077213201567120364960961965815286199604659291906768970909969119283818899578872461517336788602155693417440814335996232300768684759707497330916n, + y: 1841758248948177066704050081277018555328484709289967242827139435277985400572702195216268205445645568812241874891622506750070402046267339319053879267599690907n + }; + const point = mapper.ECPointDecompress( inputCompressedPoint ) + expect(point).toEqual(output); +}); + +//**** end of tests + +// Function for test. Eliminate this when key-did-resolver is written. + +function pubKeyHexToUint8Array(publicKeyHex: string) { + if(publicKeyHex == null) { + throw new TypeError('input cannot be null or undefined.'); + } + if(publicKeyHex.length % 2 == 0) { + return u8a.fromString(publicKeyHex,'base16'); + } else { + return u8a.fromString(('0'+publicKeyHex),'base16'); + } +} diff --git a/packages/key-did-resolver/src/index.ts b/packages/key-did-resolver/src/index.ts index d93a23dd22..9e315e20c0 100644 --- a/packages/key-did-resolver/src/index.ts +++ b/packages/key-did-resolver/src/index.ts @@ -5,30 +5,39 @@ import type { DIDResolutionOptions, ResolverRegistry, ParsedDID, - Resolver + Resolver, } from 'did-resolver' import * as secp256k1 from './secp256k1' import * as ed25519 from './ed25519' import * as secp256r1 from './secp256r1' +import * as secp384r1 from './secp384r1' +import * as secp521r1 from './secp521r1' const DID_LD_JSON = 'application/did+ld+json' const DID_JSON = 'application/did+json' // supported drivers const prefixToDriverMap: any = { - 0xE7: secp256k1, - 0xED: ed25519, - 0x1200: secp256r1, + 0xe7: secp256k1, + 0xed: ed25519, + 0x1200: secp256r1, + 0x1201: secp384r1, + 0x1202: secp521r1 } -export default { - getResolver: (): ResolverRegistry => ({ - 'key': async (did: string, parsed: ParsedDID, r: Resolver, options: DIDResolutionOptions): Promise => { +export function getResolver(): ResolverRegistry { + return { + key: async ( + did: string, + parsed: ParsedDID, + r: Resolver, + options: DIDResolutionOptions + ): Promise => { const contentType = options.accept || DID_JSON const response: DIDResolutionResult = { didResolutionMetadata: { contentType }, didDocument: null, - didDocumentMetadata: {} + didDocumentMetadata: {}, } try { const multicodecPubKey: any = multibase.decode(parsed.id) @@ -36,7 +45,7 @@ export default { const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) const doc = await prefixToDriverMap[keyType].keyToDidDoc(pubKeyBytes, parsed.id) if (contentType === DID_LD_JSON) { - doc['@context'] = 'https://w3id.org/did/v1', + doc['@context'] = 'https://w3id.org/did/v1' response.didDocument = doc } else if (contentType === DID_JSON) { response.didDocument = doc @@ -49,6 +58,9 @@ export default { response.didResolutionMetadata.message = e.toString() } return response - } - }) + }, + } } + +export default { getResolver } + diff --git a/packages/key-did-resolver/src/nist_weierstrass_common.ts b/packages/key-did-resolver/src/nist_weierstrass_common.ts new file mode 100644 index 0000000000..6671b3baee --- /dev/null +++ b/packages/key-did-resolver/src/nist_weierstrass_common.ts @@ -0,0 +1,162 @@ +// Brent Shambaugh . 2021. + +import * as u8a from 'uint8arrays' +import multibase from'multibase' +//import * as bigintModArith from 'bigint-mod-arith' + +/** + * x,y point as a BigInt (requires at least ES2020) + * For BigInt see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt + */ +interface BigIntPoint { + x: BigInt, + y : BigInt +} + +/** + * xm,ym point with components expresse with base64url utilizing multiformats + * + * base64url is expressed in the Multibase Table: https://github.com/multiformats/multibase/blob/master/multibase.csv + */ +interface base64urlPoint { + xm: string, + ym: string +} + +/** + * Elliptic curve point with coordinates expressed as byte arrays (Uint8Array) + */ +interface octetPoint { + xOctet: Uint8Array, + yOctet: Uint8Array +} + +/** + * Converts a byte array into a Hex String. + * + * @param pubKeyBytes - public key + * @returns hex string + * @throws TypeError: input cannot be null or undefined. + */ +export function pubKeyBytesToHex(pubKeyBytes: Uint8Array) : string { + if(!testUint8Array(pubKeyBytes)) { + throw new TypeError('input must be a Uint8Array'); + } + const bbf = u8a.toString(pubKeyBytes,'base16') + return bbf; +} + +/** + * + * @param publicKeyHex - public key as hex string. + * @returns + * @throws TypeError: input cannot be null or undefined. + */ +export function publicKeyToXY(publicKeyHex: string) : base64urlPoint { + if(!testHexString(publicKeyHex)) { + throw new TypeError('input must be string with characters 0-9,A-F,a-f'); + } + const u8aOctetPoint = publicKeyHexToUint8ArrayPointPair(publicKeyHex); + const xm = (u8a.toString(multibase.encode('base64url',u8aOctetPoint.xOctet))).slice(1); + const ym = (u8a.toString(multibase.encode('base64url',u8aOctetPoint.yOctet))).slice(1); + return { xm, ym }; +} + +/** + * + * @param publicKeyHex - public key as hex string. + * @returns - point with Uint8Array bytes using base16 + * @throws TypeError: input cannot be null or undefined. + */ +export function publicKeyHexToUint8ArrayPointPair(publicKeyHex: string) : octetPoint { + if(!testHexString(publicKeyHex)) { + throw new TypeError('input must be string with characters 0-9,A-F,a-f'); + } + const xHex = publicKeyHex.slice(0,publicKeyHex.length/2); + const yHex = publicKeyHex.slice(publicKeyHex.length/2,publicKeyHex.length); + const xOctet = u8a.fromString(xHex,'base16'); + const yOctet = u8a.fromString(yHex,'base16'); + return { xOctet, yOctet }; +} + +/** + * Tests to see if the argument is a Hex String. + * @param str + * @returns + */ +export function testHexString(str : string) : boolean { + const regex = new RegExp(/^[A-Fa-f0-9]+/i); + if(regex.test(str)) { + if(str.length == regex.exec(str)[0].length) { + return true; + } + } + return false; +} + +/** + * Test to see if the argument is the Uint8Array + * @param param + * @returns + */ +export function testUint8Array(param: Uint8Array) : boolean { + if(param == null) { + return false; + } + if(param.constructor === Uint8Array) { + return true; + } else { + return false; + } +} + + +/** + * + * @param ecpoint - Public key. + * @returns Uint8Array with bytes as base16 + * @throws TypeError: input cannot be null or undefined. + * @throws Error: Input coordinates must be BigInt + * @throws Error: Input must have properties x and y + * @throws TypeError: Input must be an object with properties x and y + * Points xm and ym follow the base64url format in JSON Web Key (JWK) in RFC 7517: https://datatracker.ietf.org/doc/html/rfc7517 +*/ +export function publicKeyIntToXY(ecpoint: BigIntPoint): base64urlPoint { + if(ecpoint == null) { throw new TypeError('input cannot be null or undefined.'); } + + if(typeof ecpoint !== "object") { throw new TypeError("Input must be an object with properties x and y"); } + + if(!Object.prototype.hasOwnProperty.call(ecpoint, "x") || !Object.prototype.hasOwnProperty.call(ecpoint, "y")) { throw new Error("Input must have properties x and y"); } + + if(typeof ecpoint.x !== "bigint" && typeof ecpoint.y !== "bigint") { throw new Error("Input coordinates must be BigInt"); } + + const u8aOctetPoint = publicKeyIntToUint8ArrayPointPair(ecpoint); + const xm = (u8a.toString(multibase.encode('base64url',u8aOctetPoint.xOctet))).slice(1); + const ym = (u8a.toString(multibase.encode('base64url',u8aOctetPoint.yOctet))).slice(1); + return { xm, ym }; +} + +/** + * + * @param ecpoint - Public key. + * @returns Uint8Array with bytes as base10 + * @throws TypeError: input cannot be null or undefined. + * @throws Error: Input coordinates must be BigInt + * @throws Error: Input must have properties x and y + * @throws TypeError: Input must be an object with properties x and y + */ +export function publicKeyIntToUint8ArrayPointPair(ecpoint: BigIntPoint) : octetPoint { + if(ecpoint == null) { throw new TypeError('input cannot be null or undefined.'); } + + if(typeof ecpoint !== "object") { throw new TypeError("Input must be an object with properties x and y"); } + + if(!Object.prototype.hasOwnProperty.call(ecpoint, "x") || !Object.prototype.hasOwnProperty.call(ecpoint, "y")) { throw new Error("Input must have properties x and y"); } + + if(typeof ecpoint.x !== "bigint" && typeof ecpoint.y !== "bigint") { throw new Error("Input coordinates must be BigInt"); } + + const xHex = (ecpoint.x).toString(); + const yHex = (ecpoint.y).toString(); + const xOctet = u8a.fromString(xHex,'base10'); + const yOctet = u8a.fromString(yHex,'base10'); + return { xOctet, yOctet }; +} diff --git a/packages/key-did-resolver/src/secp256r1.ts b/packages/key-did-resolver/src/secp256r1.ts index be009c81fd..3a5bc356ff 100644 --- a/packages/key-did-resolver/src/secp256r1.ts +++ b/packages/key-did-resolver/src/secp256r1.ts @@ -1,9 +1,10 @@ // Brent Shambaugh . 2021. import * as u8a from 'uint8arrays' -import multibase from'multibase' import * as bigintModArith from 'bigint-mod-arith' +import * as nist_weierstrass_common from './nist_weierstrass_common' + /** * x,y point as a BigInt (requires at least ES2020) * For BigInt see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt @@ -23,14 +24,6 @@ interface base64urlPoint { ym: string } -/** - * Elliptic curve point with coordinates expressed as byte arrays (Uint8Array) - */ -interface octetPoint { - xOctet: Uint8Array, - yOctet: Uint8Array -} - /** * Constructs the document based on the method key */ @@ -58,21 +51,6 @@ export function keyToDidDoc (pubKeyBytes: Uint8Array, fingerprint: string): any } } -/** - * Converts a byte array into a Hex String. - * - * @param pubKeyBytes - public key - * @returns hex string - * @throws TypeError: input cannot be null or undefined. - */ -export function pubKeyBytesToHex(pubKeyBytes: Uint8Array) : string { - if(!testUint8Array(pubKeyBytes)) { - throw new TypeError('input must be a Uint8Array'); - } - const bbf = u8a.toString(pubKeyBytes,'base16') - return bbf; -} - /** * Decompress a compressed public key in SEC format. * See section 2.3.3 in SEC 1 v2 : https://www.secg.org/sec1-v2.pdf. @@ -83,7 +61,7 @@ export function pubKeyBytesToHex(pubKeyBytes: Uint8Array) : string { * @throws TypeError: input cannot be null or undefined. */ export function ECPointDecompress( comp : Uint8Array ) : BigIntPoint { - if(!testUint8Array(comp)) { + if(!nist_weierstrass_common.testUint8Array(comp)) { throw new TypeError('input must be a Uint8Array'); } // two, prime, b, and pIdent are constants for the P-256 curve @@ -113,120 +91,6 @@ export function pubKeyBytesToHex(pubKeyBytes: Uint8Array) : string { } -/** - * - * @param publicKeyHex - public key as hex string. - * @returns - * @throws TypeError: input cannot be null or undefined. - */ -export function publicKeyToXY(publicKeyHex: string) : base64urlPoint { - if(!testHexString(publicKeyHex)) { - throw new TypeError('input must be string with characters 0-9,A-F,a-f'); - } - const u8aOctetPoint = publicKeyHexToUint8ArrayPointPair(publicKeyHex); - const xm = u8a.toString(multibase.encode('base64url',u8aOctetPoint.xOctet)); - const ym = u8a.toString(multibase.encode('base64url',u8aOctetPoint.yOctet)); - return { xm, ym }; -} - -/** - * - * @param publicKeyHex - public key as hex string. - * @returns - point with Uint8Array bytes using base16 - * @throws TypeError: input cannot be null or undefined. - */ -export function publicKeyHexToUint8ArrayPointPair(publicKeyHex: string) : octetPoint { - if(!testHexString(publicKeyHex)) { - throw new TypeError('input must be string with characters 0-9,A-F,a-f'); - } - const xHex = publicKeyHex.slice(0,publicKeyHex.length/2); - const yHex = publicKeyHex.slice(publicKeyHex.length/2,publicKeyHex.length); - const xOctet = u8a.fromString(xHex,'base16'); - const yOctet = u8a.fromString(yHex,'base16'); - return { xOctet, yOctet }; -} - -/** - * Tests to see if the argument is a Hex String. - * @param str - * @returns - */ -export function testHexString(str : string) : boolean { - const regex = new RegExp(/^[A-Fa-f0-9]+/i); - if(regex.test(str)) { - if(str.length == regex.exec(str)[0].length) { - return true; - } - } - return false; -} - -/** - * Test to see if the argument is the Uint8Array - * @param param - * @returns - */ -export function testUint8Array(param: Uint8Array) : boolean { - if(param == null) { - return false; - } - if(param.constructor === Uint8Array) { - return true; - } else { - return false; - } -} - - -/** - * - * @param ecpoint - Public key. - * @returns Uint8Array with bytes as base16 - * @throws TypeError: input cannot be null or undefined. - * @throws Error: Input coordinates must be BigInt - * @throws Error: Input must have properties x and y - * @throws TypeError: Input must be an object with properties x and y -*/ -export function publicKeyIntToXY(ecpoint: BigIntPoint): base64urlPoint { - if(ecpoint == null) { throw new TypeError('input cannot be null or undefined.'); } - - if(typeof ecpoint !== "object") { throw new TypeError("Input must be an object with properties x and y"); } - - if(!Object.prototype.hasOwnProperty.call(ecpoint, "x") || !Object.prototype.hasOwnProperty.call(ecpoint, "y")) { throw new Error("Input must have properties x and y"); } - - if(typeof ecpoint.x !== "bigint" && typeof ecpoint.y !== "bigint") { throw new Error("Input coordinates must be BigInt"); } - - const u8aOctetPoint = publicKeyIntToUint8ArrayPointPair(ecpoint); - const xm = u8a.toString(multibase.encode('base64url',u8aOctetPoint.xOctet)); - const ym = u8a.toString(multibase.encode('base64url',u8aOctetPoint.yOctet)); - return { xm, ym }; -} - -/** - * - * @param ecpoint - Public key. - * @returns Uint8Array with bytes as base10 - * @throws TypeError: input cannot be null or undefined. - * @throws Error: Input coordinates must be BigInt - * @throws Error: Input must have properties x and y - * @throws TypeError: Input must be an object with properties x and y - */ -export function publicKeyIntToUint8ArrayPointPair(ecpoint: BigIntPoint) : octetPoint { - if(ecpoint == null) { throw new TypeError('input cannot be null or undefined.'); } - - if(typeof ecpoint !== "object") { throw new TypeError("Input must be an object with properties x and y"); } - - if(!Object.prototype.hasOwnProperty.call(ecpoint, "x") || !Object.prototype.hasOwnProperty.call(ecpoint, "y")) { throw new Error("Input must have properties x and y"); } - - if(typeof ecpoint.x !== "bigint" && typeof ecpoint.y !== "bigint") { throw new Error("Input coordinates must be BigInt"); } - - const xHex = (ecpoint.x).toString(); - const yHex = (ecpoint.y).toString(); - const xOctet = u8a.fromString(xHex,'base10'); - const yOctet = u8a.fromString(yHex,'base10'); - return { xOctet, yOctet }; -} - /** * * @param pubKeyBytes - public key as uncompressed byte array with no prefix (raw key), @@ -240,22 +104,22 @@ export function publicKeyIntToUint8ArrayPointPair(ecpoint: BigIntPoint) : octetP * @internal */ export function pubKeyBytesToXY(pubKeyBytes: Uint8Array) : base64urlPoint { - if(!testUint8Array(pubKeyBytes)) { + if(!nist_weierstrass_common.testUint8Array(pubKeyBytes)) { throw new TypeError('input must be a Uint8Array'); } - const publicKeyHex = pubKeyBytesToHex(pubKeyBytes); + const publicKeyHex = nist_weierstrass_common.pubKeyBytesToHex(pubKeyBytes); const bytesCount = publicKeyHex.length / 2; // raw p-256 key if(bytesCount == 64) { - return publicKeyToXY(publicKeyHex); + return nist_weierstrass_common.publicKeyToXY(publicKeyHex); } // uncompressed p-256 key, SEC format if(bytesCount == 65) { if(publicKeyHex.slice(0,2) == '04') { const publicKey = publicKeyHex.slice(2); - return publicKeyToXY(publicKey); + return nist_weierstrass_common.publicKeyToXY(publicKey); } } @@ -264,7 +128,7 @@ export function pubKeyBytesToXY(pubKeyBytes: Uint8Array) : base64urlPoint { if(publicKeyHex.slice(0,2) == '03' || publicKeyHex.slice(0,2) == '02') { const publicKey = u8a.fromString(publicKeyHex,'base16') const point = ECPointDecompress(publicKey); - return publicKeyIntToXY(point); + return nist_weierstrass_common.publicKeyIntToXY(point); } } diff --git a/packages/key-did-resolver/src/secp384r1.ts b/packages/key-did-resolver/src/secp384r1.ts new file mode 100644 index 0000000000..9126f8587e --- /dev/null +++ b/packages/key-did-resolver/src/secp384r1.ts @@ -0,0 +1,136 @@ +// Brent Shambaugh . 2021. + +import * as u8a from 'uint8arrays' +import * as bigintModArith from 'bigint-mod-arith' + +import * as nist_weierstrass_common from './nist_weierstrass_common' + +/** + * x,y point as a BigInt (requires at least ES2020) + * For BigInt see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt + */ +interface BigIntPoint { + x: BigInt, + y : BigInt +} + +/** + * xm,ym point with components expresse with base64url utilizing multiformats + * + * base64url is expressed in the Multibase Table: https://github.com/multiformats/multibase/blob/master/multibase.csv + */ +interface base64urlPoint { + xm: string, + ym: string +} + +/** + * Constructs the document based on the method key + */ +export function keyToDidDoc (pubKeyBytes: Uint8Array, fingerprint: string): any { + const did = `did:key:${fingerprint}` + const keyId = `${did}#${fingerprint}` + const key = pubKeyBytesToXY(pubKeyBytes); + return { + id: did, + verificationMethod: [{ + id: keyId, + type: 'JsonWebKey2020', + controller: did, + publicKeyJwk: { + kty: "EC", + crv: "P-384", + x: key.xm, + y: key.ym, + }, + }], + authentication: [keyId], + assertionMethod: [keyId], + capabilityDelegation: [keyId], + capabilityInvocation: [keyId], + } + } + +/** + * Decompress a compressed public key in SEC format. + * See section 2.3.3 in SEC 1 v2 : https://www.secg.org/sec1-v2.pdf. + * + * Code based on: https://stackoverflow.com/questions/17171542/algorithm-for-elliptic-curve-point-compression/30431547#30431547 + * + * @param - 49 byte compressed public key. 1st byte: 0x02 for even or 0x03 for odd. Following 32 bytes: x coordinate expressed as big-endian. + * @throws TypeError: input cannot be null or undefined. + */ + export function ECPointDecompress( comp : Uint8Array ) : BigIntPoint { + if(!nist_weierstrass_common.testUint8Array(comp)) { + throw new TypeError('input must be a Uint8Array'); + } + // two, prime, b, and pIdent are constants for the P-384 curve + const two = BigInt(2); + const prime = (two ** 384n) - (two ** 128n) - (two ** 96n) + (two ** 32n ) - 1n; + const b = 27580193559959705877849011840389048093056905856361568521428707301988689241309860865136260764883745107765439761230575n; + const pIdent = (prime + 1n) / 4n; + + const signY = BigInt(comp[0] - 2); + const x = comp.subarray(1); + const xBig = BigInt(u8a.toString(x,'base10')); + + const a = xBig**3n - xBig*3n + b; + let yBig = bigintModArith.modPow(a,pIdent,prime); + + // "// If the parity doesn't match it's the *other* root" + if( yBig % 2n !== signY) + { + // y = prime - y + yBig = prime - yBig; + } + + return { + x: xBig, + y: yBig + }; + +} + +/** + * + * @param pubKeyBytes - public key as uncompressed byte array with no prefix (raw key), + * uncompressed with 0x04 prefix, or compressed with 0x02 prefix if even and 0x03 prefix if odd. + * @returns point x,y with coordinates as multibase encoded base64urls + * + * See the the did:key specification: https://w3c-ccg.github.io/did-method-key/#p-384. + * At present only raw p-384 keys are covered in the specification. + * @throws TypeError: input cannot be null or undefined. + * @throws Error: Unexpected pubKeyBytes + * @internal + */ +export function pubKeyBytesToXY(pubKeyBytes: Uint8Array) : base64urlPoint { + if(!nist_weierstrass_common.testUint8Array(pubKeyBytes)) { + throw new TypeError('input must be a Uint8Array'); + } + const publicKeyHex = nist_weierstrass_common.pubKeyBytesToHex(pubKeyBytes); + const bytesCount = publicKeyHex.length / 2; + + // raw p-384 key + if(bytesCount == 96) { + return nist_weierstrass_common.publicKeyToXY(publicKeyHex); + } + + // uncompressed p-384 key, SEC format + if(bytesCount == 97) { + if(publicKeyHex.slice(0,2) == '04') { + const publicKey = publicKeyHex.slice(2); + return nist_weierstrass_common.publicKeyToXY(publicKey); + } + } + + // compressed p-384 key, SEC format + if(bytesCount == 49) { + if(publicKeyHex.slice(0,2) == '03' || publicKeyHex.slice(0,2) == '02') { + const publicKey = u8a.fromString(publicKeyHex,'base16') + const point = ECPointDecompress(publicKey); + return nist_weierstrass_common.publicKeyIntToXY(point); + } + } + + throw new Error('Unexpected pubKeyBytes'); +} diff --git a/packages/key-did-resolver/src/secp521r1.ts b/packages/key-did-resolver/src/secp521r1.ts new file mode 100644 index 0000000000..dbf74c9547 --- /dev/null +++ b/packages/key-did-resolver/src/secp521r1.ts @@ -0,0 +1,122 @@ +// Brent Shambaugh . 2021. + +import * as u8a from 'uint8arrays' +import * as bigintModArith from 'bigint-mod-arith' + +import * as nist_weierstrass_common from './nist_weierstrass_common' + +/** + * x,y point as a BigInt (requires at least ES2020) + * For BigInt see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt + */ +interface BigIntPoint { + x: BigInt, + y : BigInt +} + +/** + * xm,ym point with components expresse with base64url utilizing multiformats + * + * base64url is expressed in the Multibase Table: https://github.com/multiformats/multibase/blob/master/multibase.csv + */ +interface base64urlPoint { + xm: string, + ym: string +} + +/** + * Constructs the document based on the method key + */ +export function keyToDidDoc (pubKeyBytes: Uint8Array, fingerprint: string): any { + const did = `did:key:${fingerprint}` + const keyId = `${did}#${fingerprint}` + const key = pubKeyBytesToXY(pubKeyBytes); + return { + id: did, + verificationMethod: [{ + id: keyId, + type: 'JsonWebKey2020', + controller: did, + publicKeyJwk: { + kty: "EC", + crv: "P-521", + x: key.xm, + y: key.ym, + }, + }], + authentication: [keyId], + assertionMethod: [keyId], + capabilityDelegation: [keyId], + capabilityInvocation: [keyId], + } + } + +/** + * Decompress a compressed public key in SEC format. + * See section 2.3.3 in SEC 1 v2 : https://www.secg.org/sec1-v2.pdf. + * + * Code based on: https://stackoverflow.com/questions/17171542/algorithm-for-elliptic-curve-point-compression/30431547#30431547 + * b on page 15 of https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-186-draft.pdf + * @param - 67 byte compressed public key. 1st byte: 0x02 for even or 0x03 for odd. Following 32 bytes: x coordinate expressed as big-endian. + * @throws TypeError: input cannot be null or undefined. + */ + export function ECPointDecompress( comp : Uint8Array ) : BigIntPoint { + if(!nist_weierstrass_common.testUint8Array(comp)) { + throw new TypeError('input must be a Uint8Array'); + } + // two, prime, b, and pIdent are constants for the P-521 curve + const two = BigInt(2); + const prime = (two ** 521n) - 1n; + const b = 1093849038073734274511112390766805569936207598951683748994586394495953116150735016013708737573759623248592132296706313309438452531591012912142327488478985984n; + const pIdent = (prime + 1n) / 4n; + + const signY = BigInt(comp[0] - 2); + const x = comp.subarray(1); + const xBig = BigInt(u8a.toString(x,'base10')); + + const a = xBig**3n - xBig*3n + b; + let yBig = bigintModArith.modPow(a,pIdent,prime); + + // "// If the parity doesn't match it's the *other* root" + if( yBig % 2n !== signY) + { + // y = prime - y + yBig = prime - yBig; + } + + return { + x: xBig, + y: yBig + }; + +} + +/** + * + * @param pubKeyBytes - public key as compressed with 0x02 prefix if even and 0x03 prefix if odd. + * @returns point x,y with coordinates as multibase encoded base64urls + * + * See the the did:key specification: https://w3c-ccg.github.io/did-method-key/#p-521. + * For compression see: https://tools.ietf.org/id/draft-jivsov-ecc-compact-05.html#rfc.section.3 + * @throws TypeError: input cannot be null or undefined. + * @throws Error: Unexpected pubKeyBytes + * @internal + */ +export function pubKeyBytesToXY(pubKeyBytes: Uint8Array) : base64urlPoint { + if(!nist_weierstrass_common.testUint8Array(pubKeyBytes)) { + throw new TypeError('input must be a Uint8Array'); + } + const publicKeyHex = nist_weierstrass_common.pubKeyBytesToHex(pubKeyBytes); + + // compressed p-521 key, SEC format + // publicKeyHex.length / 2.0 = 67.0 bytes + if((132 <= publicKeyHex.length) && (publicKeyHex.length <= 134)) { + if(publicKeyHex.slice(0,2) == '03' || publicKeyHex.slice(0,2) == '02') { + const publicKey = u8a.fromString(publicKeyHex,'base16') + const point = ECPointDecompress(publicKey); + return nist_weierstrass_common.publicKeyIntToXY(point); + } + } + + throw new Error('Unexpected pubKeyBytes'); +} From 758cd94c29e35e803a8b0882b7108ee054cee12f Mon Sep 17 00:00:00 2001 From: Brent Shambaugh Date: Thu, 2 Dec 2021 11:42:30 -0600 Subject: [PATCH 03/38] create test for 'const contentType = options.accept || DID_JSON' line in key-did-resolver/src/index.ts --- .../src/__tests__/index.test.ts | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/packages/key-did-resolver/src/__tests__/index.test.ts b/packages/key-did-resolver/src/__tests__/index.test.ts index 8fe9efea45..97ca29f15d 100644 --- a/packages/key-did-resolver/src/__tests__/index.test.ts +++ b/packages/key-did-resolver/src/__tests__/index.test.ts @@ -167,4 +167,24 @@ describe('Exception mapper', () => { }) + it('expect index.js to throw an error for an unsupported media type', async () => { + const resolverRegistry = index.getResolver() + expect(resolverRegistry).not.toBeUndefined() + + const resolve = resolverRegistry.key + expect(resolve).not.toBeUndefined() + + const parsedDided25519 = { + id: "z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8", + did: 'did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8', + method: "key", + didUrl: 'did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8/some/path', + path: '/some/path' + } + + await expect(resolve('did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8', parsedDided25519, {}, { accept: null })).resolves.toEqual(expect.objectContaining({"didResolutionMetadata": {"contentType": "application/did+json"}})) + + + }) + }) From ef92d4699f0cebcab09f3d249170ff8981f07fa7 Mon Sep 17 00:00:00 2001 From: Brent Shambaugh Date: Thu, 2 Dec 2021 11:49:12 -0600 Subject: [PATCH 04/38] remove unnecessary match anything test and clean up test comments --- .../src/__tests__/index.test.ts | 23 ++----------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/packages/key-did-resolver/src/__tests__/index.test.ts b/packages/key-did-resolver/src/__tests__/index.test.ts index 97ca29f15d..bd90ceab1a 100644 --- a/packages/key-did-resolver/src/__tests__/index.test.ts +++ b/packages/key-did-resolver/src/__tests__/index.test.ts @@ -112,7 +112,7 @@ describe('Index mapper', () => { }) -describe('Exception mapper', () => { +describe('Exception mapper + default fpr options.accept', () => { it('expect index.js to throw an error for an unsupported decentralized identifier', async () => { const resolverRegistry = index.getResolver() expect(resolverRegistry).not.toBeUndefined() @@ -148,26 +148,7 @@ describe('Exception mapper', () => { await expect(resolve('did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8', parsedDided25519, {}, { accept: 'application/rdf+xml' })).resolves.toEqual({"didDocument": null, "didDocumentMetadata": {}, "didResolutionMetadata": {"error": "representationNotSupported"}}) }) - it('expect index.js to throw an error for an unsupported media type', async () => { - const resolverRegistry = index.getResolver() - expect(resolverRegistry).not.toBeUndefined() - - const resolve = resolverRegistry.key - expect(resolve).not.toBeUndefined() - - const parsedDided25519 = { - id: "z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8", - did: 'did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8', - method: "key", - didUrl: 'did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8/some/path', - path: '/some/path' - } - - await expect(resolve('did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8', parsedDided25519, {}, { accept: 'application/did+json' })).resolves.toEqual(expect.anything()) - - }) - - it('expect index.js to throw an error for an unsupported media type', async () => { + it('expect index.js to default to DID_JSON for options.accept when there is an unspecified return media type', async () => { const resolverRegistry = index.getResolver() expect(resolverRegistry).not.toBeUndefined() From d6925e9cd337436c3bc21cc1798169e06ab4bda0 Mon Sep 17 00:00:00 2001 From: Brent Shambaugh Date: Thu, 2 Dec 2021 12:43:48 -0600 Subject: [PATCH 05/38] add comment about testing key-did-resolver --- packages/key-did-resolver/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/key-did-resolver/README.md b/packages/key-did-resolver/README.md index 410d1c1643..7576993ea6 100644 --- a/packages/key-did-resolver/README.md +++ b/packages/key-did-resolver/README.md @@ -302,6 +302,8 @@ did document metadata: ] ``` +## Testing +Due to conflicts with parsing JSON with BigInt, tests need to be run with Jest in Serial mode. Use *npm run test -- --runInBand* . ## Comments During development there was not yet consensus on using all compressed keys. Support for uncompressed keys with the '04' prefix and From fcec71842c59d238a3720b5d144f138dbcc18e82 Mon Sep 17 00:00:00 2001 From: Brent Shambaugh Date: Thu, 2 Dec 2021 12:47:36 -0600 Subject: [PATCH 06/38] update formatting about testing --- packages/key-did-resolver/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/key-did-resolver/README.md b/packages/key-did-resolver/README.md index 7576993ea6..4d5dcc8fc3 100644 --- a/packages/key-did-resolver/README.md +++ b/packages/key-did-resolver/README.md @@ -303,7 +303,7 @@ did document metadata: ``` ## Testing -Due to conflicts with parsing JSON with BigInt, tests need to be run with Jest in Serial mode. Use *npm run test -- --runInBand* . +Due to problems with parsing JSON with BigInt, tests need to be run with Jest in Serial mode. Use **_npm run test -- --runInBand_** . ## Comments During development there was not yet consensus on using all compressed keys. Support for uncompressed keys with the '04' prefix and From 182671a7cc9795a07f2343edcbaf12dd3956ccd7 Mon Sep 17 00:00:00 2001 From: Brent Shambaugh Date: Thu, 2 Dec 2021 13:36:42 -0600 Subject: [PATCH 07/38] update comments for README --- packages/key-did-resolver/README.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/key-did-resolver/README.md b/packages/key-did-resolver/README.md index 4d5dcc8fc3..251216c96e 100644 --- a/packages/key-did-resolver/README.md +++ b/packages/key-did-resolver/README.md @@ -7,10 +7,7 @@ $ npm install key-did-resolver ``` ### Usage - -This code supports compressed did:keys in concordance with https://github.com/w3c-ccg/did-method-key test-vectors. - -The did:key id is the multicodec name + the compressed public key expressed as a Uint8Array (byte array) then encoded with base58btc and expressed as a string. +This code includes support for Ed25519 and Secp256k1 did:keys described in https://github.com/w3c-ccg/did-method-key . Example code for creating a did:key for Ed25519 is here: https://github.com/ceramicnetwork/key-did-provider-ed25519 @@ -18,10 +15,16 @@ https://github.com/ceramicnetwork/key-did-provider-ed25519 Example code for creating a did:key for Secp256k1 is here: https://github.com/ceramicnetwork/key-did-provider-secp256k1 +This code supports compressed forms of P-256, P-384, and P-521 did:keys in concordance with https://github.com/w3c-ccg/did-method-key test-vectors. + +The did:key id is the multicodec name + the compressed public key expressed as a Uint8Array (byte array) then encoded with base58btc and expressed as a string. +The syntax is did:key:id. + Example code for creating a did:key for P-256, P-384, and P-521 is here: https://github.com/bshambaugh/did-key-creator Compressed keys are the X coordinate of the public key with a prefix that depends on the sign of the Y curve coordinate. The prefix is '02' if even and '03' if odd. + More information is here: https://tools.ietf.org/id/draft-jivsov-ecc-compact-05.html . ## Code From 522da642aea921cc328efeff10fd361ec89207cb Mon Sep 17 00:00:00 2001 From: Brent Shambaugh Date: Thu, 2 Dec 2021 13:38:23 -0600 Subject: [PATCH 08/38] fix typo --- packages/key-did-resolver/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/key-did-resolver/README.md b/packages/key-did-resolver/README.md index 251216c96e..430a80e8ac 100644 --- a/packages/key-did-resolver/README.md +++ b/packages/key-did-resolver/README.md @@ -18,7 +18,7 @@ https://github.com/ceramicnetwork/key-did-provider-secp256k1 This code supports compressed forms of P-256, P-384, and P-521 did:keys in concordance with https://github.com/w3c-ccg/did-method-key test-vectors. The did:key id is the multicodec name + the compressed public key expressed as a Uint8Array (byte array) then encoded with base58btc and expressed as a string. -The syntax is did:key:id. +The syntax of a did:key is did:key:id. Example code for creating a did:key for P-256, P-384, and P-521 is here: https://github.com/bshambaugh/did-key-creator From 628ff1d421b8e5c217a24dde08ebbbe7693e76f2 Mon Sep 17 00:00:00 2001 From: Brent Shambaugh Date: Thu, 2 Dec 2021 15:17:08 -0600 Subject: [PATCH 09/38] Update README with references --- packages/key-did-resolver/README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/packages/key-did-resolver/README.md b/packages/key-did-resolver/README.md index 430a80e8ac..d08838b784 100644 --- a/packages/key-did-resolver/README.md +++ b/packages/key-did-resolver/README.md @@ -312,6 +312,19 @@ Due to problems with parsing JSON with BigInt, tests need to be run with Jest in During development there was not yet consensus on using all compressed keys. Support for uncompressed keys with the '04' prefix and raw keys (just the x,y bytes with no prefix) was kept for the P-256 and P-384 curves. +## References + +[Standards for Efficient Cryptography +SEC 2: Recommended Elliptic Curve Domain Parameters +Certicom Research +Contact: Daniel R. L. Brown (dbrown@certicom.com) +January 27, 2010 +Version 2.0 ], http://www.secg.org/sec2-v2.pdf + + +[FIPS PUB 186-4 ,FEDERAL INFORMATION PROCESSING STANDARDS +PUBLICATION, Digital Signature Standard (DSS)], https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf + ## Contributing We are happy to accept small and large contributions. Make sure to check out the [Ceramic specifications](https://github.com/ceramicnetwork/specs) for details of how the protocol works. From 5dc23da03eec2a673fa986f8438d6ae01431e261 Mon Sep 17 00:00:00 2001 From: Brent Shambaugh Date: Thu, 2 Dec 2021 15:24:12 -0600 Subject: [PATCH 10/38] reformat README. move an additional reference to the end --- packages/key-did-resolver/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/key-did-resolver/README.md b/packages/key-did-resolver/README.md index d08838b784..f46e587959 100644 --- a/packages/key-did-resolver/README.md +++ b/packages/key-did-resolver/README.md @@ -25,8 +25,6 @@ https://github.com/bshambaugh/did-key-creator Compressed keys are the X coordinate of the public key with a prefix that depends on the sign of the Y curve coordinate. The prefix is '02' if even and '03' if odd. -More information is here: https://tools.ietf.org/id/draft-jivsov-ecc-compact-05.html . - ## Code ``` // Usage from cloned GitHub Repository: @@ -325,6 +323,9 @@ Version 2.0 ], http://www.secg.org/sec2-v2.pdf [FIPS PUB 186-4 ,FEDERAL INFORMATION PROCESSING STANDARDS PUBLICATION, Digital Signature Standard (DSS)], https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf +[Compact representation of an elliptic curve point, Network Working Group, A.J. Jivsov, March 15, 2014], +https://tools.ietf.org/id/draft-jivsov-ecc-compact-05.html + ## Contributing We are happy to accept small and large contributions. Make sure to check out the [Ceramic specifications](https://github.com/ceramicnetwork/specs) for details of how the protocol works. From 316ab44f487703b824e7349d5ad527379eb03f86 Mon Sep 17 00:00:00 2001 From: Brent Shambaugh Date: Thu, 2 Dec 2021 15:26:39 -0600 Subject: [PATCH 11/38] reformat readme --- packages/key-did-resolver/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/key-did-resolver/README.md b/packages/key-did-resolver/README.md index f46e587959..860bdc6b10 100644 --- a/packages/key-did-resolver/README.md +++ b/packages/key-did-resolver/README.md @@ -20,11 +20,11 @@ This code supports compressed forms of P-256, P-384, and P-521 did:keys in conco The did:key id is the multicodec name + the compressed public key expressed as a Uint8Array (byte array) then encoded with base58btc and expressed as a string. The syntax of a did:key is did:key:id. +Compressed keys are the X coordinate of the public key with a prefix that depends on the sign of the Y curve coordinate. The prefix is '02' if even and '03' if odd. + Example code for creating a did:key for P-256, P-384, and P-521 is here: https://github.com/bshambaugh/did-key-creator -Compressed keys are the X coordinate of the public key with a prefix that depends on the sign of the Y curve coordinate. The prefix is '02' if even and '03' if odd. - ## Code ``` // Usage from cloned GitHub Repository: From 7e02d8fcd56c915df7dc91fe26a517705cd84d4b Mon Sep 17 00:00:00 2001 From: Brent Shambaugh Date: Wed, 8 Dec 2021 14:51:37 -0600 Subject: [PATCH 12/38] update readme with preliminary new code, draft in progress --- packages/key-did-resolver/README.md | 45 ++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/packages/key-did-resolver/README.md b/packages/key-did-resolver/README.md index 860bdc6b10..c67a385f9a 100644 --- a/packages/key-did-resolver/README.md +++ b/packages/key-did-resolver/README.md @@ -25,7 +25,50 @@ Compressed keys are the X coordinate of the public key with a prefix that depend Example code for creating a did:key for P-256, P-384, and P-521 is here: https://github.com/bshambaugh/did-key-creator -## Code +### Code +Using @ceramicnetwork/core with secp256k1 did-key: +``` +import KeyDIDResolver from 'key-did-resolver' +import {Resolver} from 'did-resolver' +import {Ceramic} from '@ceramicnetwork/core' +import * as IPFS from 'ipfs-core' +import dagJose from 'dag-jose' +import {convert} from 'blockcodec-to-ipld-format' + +const format = convert(dagJose) + +const ipfs = await IPFS.create({ + ipld: { formats: [format] }, +}) + +const config = {} +const ceramic = await Ceramic.create(ipfs, config) +const keyDidResolver = KeyDIDResolver.getResolver(ceramic) +console.log(keyDidResolver) +const didResolver = new Resolver(keyDidResolver) +const doc = await didResolver.resolve('did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8') + +console.log(doc) +console.log(doc.didDocument.verificationMethod) +``` + +Using @ceramicnetwork/http-client with secp256k1 did-key: +``` +import KeyDIDResolver from 'key-did-resolver' +import {Resolver} from 'did-resolver' + +import { CeramicClient } from '@ceramicnetwork/http-client' +const API_URL = "https://ceramic-clay.3boxlabs.com" // or your ceramic endpoint +const ceramic = new CeramicClient(API_URL) + +const keyDidResolver = KeyDIDResolver.getResolver(ceramic) +const didResolver = new Resolver(keyDidResolver) +const doc = await didResolver.resolve('did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme') + +console.log(doc) +console.log(doc.didDocument.verificationMethod) +``` + ``` // Usage from cloned GitHub Repository: // import * as keyDIDResolver from '../js-ceramic/packages/key-did-resolver/lib/index.js'; From e71a5701595f6739627b44b3fa97036360469460 Mon Sep 17 00:00:00 2001 From: Brent Shambaugh Date: Wed, 8 Dec 2021 14:54:56 -0600 Subject: [PATCH 13/38] test a hyperlink in README --- packages/key-did-resolver/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/key-did-resolver/README.md b/packages/key-did-resolver/README.md index c67a385f9a..33ac4c1fb2 100644 --- a/packages/key-did-resolver/README.md +++ b/packages/key-did-resolver/README.md @@ -26,7 +26,7 @@ Example code for creating a did:key for P-256, P-384, and P-521 is here: https://github.com/bshambaugh/did-key-creator ### Code -Using @ceramicnetwork/core with secp256k1 did-key: +Using [@ceramicnetwork/core](https://developers.ceramic.network/reference/typescript/modules/_ceramicnetwork_core.html) with secp256k1 did-key: ``` import KeyDIDResolver from 'key-did-resolver' import {Resolver} from 'did-resolver' From bc37ee417a5511f6c7e817d8e20a0d6f391cc94e Mon Sep 17 00:00:00 2001 From: Brent Shambaugh Date: Wed, 8 Dec 2021 15:02:13 -0600 Subject: [PATCH 14/38] add additional documentation to README, still in draft --- packages/key-did-resolver/README.md | 75 ++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 2 deletions(-) diff --git a/packages/key-did-resolver/README.md b/packages/key-did-resolver/README.md index 33ac4c1fb2..7a9d995511 100644 --- a/packages/key-did-resolver/README.md +++ b/packages/key-did-resolver/README.md @@ -52,7 +52,7 @@ console.log(doc) console.log(doc.didDocument.verificationMethod) ``` -Using @ceramicnetwork/http-client with secp256k1 did-key: +Using [@ceramicnetwork/http-client](https://developers.ceramic.network/reference/typescript/modules/_ceramicnetwork_http_client.html) with secp256k1 did-key: ``` import KeyDIDResolver from 'key-did-resolver' import {Resolver} from 'did-resolver' @@ -171,7 +171,78 @@ console.log(doc521.didDocument.verificationMethod); ``` -## Output +##$ Output +``` +{ + didResolutionMetadata: { contentType: 'application/did+json' }, + didDocument: { + id: 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme', + verificationMethod: [ [Object] ], + authentication: [ + 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme#zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme' + ], + assertionMethod: [ + 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme#zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme' + ], + capabilityDelegation: [ + 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme#zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme' + ], + capabilityInvocation: [ + 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme#zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme' + ] + }, + didDocumentMetadata: {} +} +[ + { + id: 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme#zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme', + type: 'Secp256k1VerificationKey2018', + controller: 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme', + publicKeyBase58: '23o6Sau8NxxzXcgSc3PLcNxrzrZpbLeBn1izfv3jbKhuv' + } +] +``` + +``` +Swarm listening on /ip4/127.0.0.1/tcp/4011/p2p/QmYGmd8VoQ1sZ82diHEzhbPxfrjrxryLMnJem4UaNnEf8K +Swarm listening on /ip4/10.0.0.5/tcp/4011/p2p/QmYGmd8VoQ1sZ82diHEzhbPxfrjrxryLMnJem4UaNnEf8K +Swarm listening on /ip4/127.0.0.1/tcp/4012/ws/p2p/QmYGmd8VoQ1sZ82diHEzhbPxfrjrxryLMnJem4UaNnEf8K +Swarm listening on /ip4/10.0.0.5/tcp/4012/ws/p2p/QmYGmd8VoQ1sZ82diHEzhbPxfrjrxryLMnJem4UaNnEf8K +Connecting to ceramic network 'inmemory' using pubsub topic '/ceramic/inmemory-2974851949' +Peer discovery is not supported for ceramic network: inmemory. This node may fail to load documents from other nodes on the network. +This node with peerId QmYGmd8VoQ1sZ82diHEzhbPxfrjrxryLMnJem4UaNnEf8K is not included in the peer list for Ceramic network inmemory. It will not be discoverable by other nodes in the network, and so data created against this node will not be available to the rest of the network. +Connected to anchor service '' with supported anchor chains ['inmemory:12345'] +{ key: [AsyncFunction: key] } +{ + didResolutionMetadata: { contentType: 'application/did+json' }, + didDocument: { + id: 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme', + verificationMethod: [ [Object] ], + authentication: [ + 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme#zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme' + ], + assertionMethod: [ + 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme#zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme' + ], + capabilityDelegation: [ + 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme#zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme' + ], + capabilityInvocation: [ + 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme#zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme' + ] + }, + didDocumentMetadata: {} +} +[ + { + id: 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme#zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme', + type: 'Secp256k1VerificationKey2018', + controller: 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme', + publicKeyBase58: '23o6Sau8NxxzXcgSc3PLcNxrzrZpbLeBn1izfv3jbKhuv' + } +] +``` + ``` did document for ed25519: From e49dca7596128f2bd3b7ee33b5565ea1dd9f983a Mon Sep 17 00:00:00 2001 From: Brent Shambaugh Date: Wed, 8 Dec 2021 15:08:35 -0600 Subject: [PATCH 15/38] further cleanup of README --- packages/key-did-resolver/README.md | 77 ++++++++++++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-) diff --git a/packages/key-did-resolver/README.md b/packages/key-did-resolver/README.md index 7a9d995511..759fb9d60f 100644 --- a/packages/key-did-resolver/README.md +++ b/packages/key-did-resolver/README.md @@ -69,6 +69,81 @@ console.log(doc) console.log(doc.didDocument.verificationMethod) ``` +### Output +Using [@ceramicnetwork/core](https://developers.ceramic.network/reference/typescript/modules/_ceramicnetwork_core.html) with secp256k1 did-key: +``` +{ + didResolutionMetadata: { contentType: 'application/did+json' }, + didDocument: { + id: 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme', + verificationMethod: [ [Object] ], + authentication: [ + 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme#zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme' + ], + assertionMethod: [ + 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme#zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme' + ], + capabilityDelegation: [ + 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme#zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme' + ], + capabilityInvocation: [ + 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme#zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme' + ] + }, + didDocumentMetadata: {} +} +[ + { + id: 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme#zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme', + type: 'Secp256k1VerificationKey2018', + controller: 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme', + publicKeyBase58: '23o6Sau8NxxzXcgSc3PLcNxrzrZpbLeBn1izfv3jbKhuv' + } +] + +``` +Using [@ceramicnetwork/http-client](https://developers.ceramic.network/reference/typescript/modules/_ceramicnetwork_http_client.html) with secp256k1 did-key: +``` +Swarm listening on /ip4/127.0.0.1/tcp/4011/p2p/QmYGmd8VoQ1sZ82diHEzhbPxfrjrxryLMnJem4UaNnEf8K +Swarm listening on /ip4/10.0.0.5/tcp/4011/p2p/QmYGmd8VoQ1sZ82diHEzhbPxfrjrxryLMnJem4UaNnEf8K +Swarm listening on /ip4/127.0.0.1/tcp/4012/ws/p2p/QmYGmd8VoQ1sZ82diHEzhbPxfrjrxryLMnJem4UaNnEf8K +Swarm listening on /ip4/10.0.0.5/tcp/4012/ws/p2p/QmYGmd8VoQ1sZ82diHEzhbPxfrjrxryLMnJem4UaNnEf8K +Connecting to ceramic network 'inmemory' using pubsub topic '/ceramic/inmemory-2974851949' +Peer discovery is not supported for ceramic network: inmemory. This node may fail to load documents from other nodes on the network. +This node with peerId QmYGmd8VoQ1sZ82diHEzhbPxfrjrxryLMnJem4UaNnEf8K is not included in the peer list for Ceramic network inmemory. It will not be discoverable by other nodes in the network, and so data created against this node will not be available to the rest of the network. +Connected to anchor service '' with supported anchor chains ['inmemory:12345'] +{ key: [AsyncFunction: key] } +{ + didResolutionMetadata: { contentType: 'application/did+json' }, + didDocument: { + id: 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme', + verificationMethod: [ [Object] ], + authentication: [ + 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme#zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme' + ], + assertionMethod: [ + 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme#zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme' + ], + capabilityDelegation: [ + 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme#zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme' + ], + capabilityInvocation: [ + 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme#zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme' + ] + }, + didDocumentMetadata: {} +} +[ + { + id: 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme#zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme', + type: 'Secp256k1VerificationKey2018', + controller: 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme', + publicKeyBase58: '23o6Sau8NxxzXcgSc3PLcNxrzrZpbLeBn1izfv3jbKhuv' + } +] + +``` + ``` // Usage from cloned GitHub Repository: // import * as keyDIDResolver from '../js-ceramic/packages/key-did-resolver/lib/index.js'; @@ -171,7 +246,7 @@ console.log(doc521.didDocument.verificationMethod); ``` -##$ Output +### Output ``` { didResolutionMetadata: { contentType: 'application/did+json' }, From 51b953cb2ad1c4567c6eb691fd6b3407643d585f Mon Sep 17 00:00:00 2001 From: Brent Shambaugh Date: Wed, 8 Dec 2021 15:35:08 -0600 Subject: [PATCH 16/38] add new content to README.md --- packages/key-did-resolver/README.md | 83 +++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/packages/key-did-resolver/README.md b/packages/key-did-resolver/README.md index 759fb9d60f..c3ea004c99 100644 --- a/packages/key-did-resolver/README.md +++ b/packages/key-did-resolver/README.md @@ -142,8 +142,91 @@ Connected to anchor service '' with supported anchor chains ['inmemory } ] +``` +// code snippet for ed25519 +``` +const doc = await didResolver.resolve('did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8') +``` + +// code snippet for P-256 +``` +const doc = await didResolver.resolve('did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu') +``` + +// code snippet for P-384 +``` +const doc = await didResolver.resolve('did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54') +``` + +// code snippet for P-521 +``` +const doc = await didResolver.resolve('did:key:z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t') +``` + +// Note: All P-*** curves are compressed + +// did document verificationMethod for ed25519: +``` +[ + { + id: 'did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8#z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8', + type: 'Ed25519VerificationKey2018', + controller: 'did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8', + publicKeyBase58: 'FUaAP6i2XyyouPds73QneYgZJ86qhua2jaZYBqJSwKok' + } +] +``` + +// did document verificationMethod for P-256: +``` +[ + { + id: 'did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu', + type: 'JsonWebKey2020', + controller: 'did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu', + publicKeyJwk: { + kty: 'EC', + crv: 'P-256', + x: 'OcPddBMXKURtwbPaZ9SfwEb8vwcvzFufpRwFuXQwf5Y', + y: 'nEA7FjXwRJ8CvUInUeMxIaRDTxUvKysqP2dSGcXZJfY' + } + } +] ``` +// did document verificationMethod for P-384: +``` +[ + { + id: 'did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54', + type: 'JsonWebKey2020', + controller: 'did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54', + publicKeyJwk: { + kty: 'EC', + crv: 'P-384', + x: 'CA-iNoHDg1lL8pvX3d1uvExzVfCz7Rn6tW781Ub8K5MrDf2IMPyL0RTDiaLHC1JT', + y: 'Kpnrn8DkXUD3ge4mFxi-DKr0DYO2KuJdwNBrhzLRtfMa3WFMZBiPKUPfJj8dYNl_' + } + } +] +``` + +// did document verificationMethod for P-521: +``` +[ + { + id: 'did:key:z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t', + type: 'JsonWebKey2020', + controller: 'did:key:z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t', + publicKeyJwk: { + kty: 'EC', + crv: 'P-521', + x: 'ATkofCC8_KAAJ3XSRayyPk8WqF9qahhoQVjbHtzbe5MSaaFiMKBZr-CurF9IcpJD-YYEukPmarSKFpXLtwAdiONT', + y: 'AWuYkJ7iaFhfz_dzFemaBnuq1WFnoZeIha7KpE9benPTX9FQhAoyHY-2qO4IyqGe1XGGtx8eJXvp57xMtUXm2rAH' + } + } +] +``` ``` // Usage from cloned GitHub Repository: // import * as keyDIDResolver from '../js-ceramic/packages/key-did-resolver/lib/index.js'; From a5747cccfb1df13904ce959c7e8c9f9b23b2f73b Mon Sep 17 00:00:00 2001 From: Brent Shambaugh Date: Wed, 8 Dec 2021 15:46:49 -0600 Subject: [PATCH 17/38] finalize comments with README --- packages/key-did-resolver/README.md | 377 ++-------------------------- 1 file changed, 17 insertions(+), 360 deletions(-) diff --git a/packages/key-did-resolver/README.md b/packages/key-did-resolver/README.md index c3ea004c99..70606f94f7 100644 --- a/packages/key-did-resolver/README.md +++ b/packages/key-did-resolver/README.md @@ -54,6 +54,8 @@ console.log(doc.didDocument.verificationMethod) Using [@ceramicnetwork/http-client](https://developers.ceramic.network/reference/typescript/modules/_ceramicnetwork_http_client.html) with secp256k1 did-key: ``` +// Usage from cloned GitHub Repository: +// import * as keyDIDResolver from '../js-ceramic/packages/key-did-resolver/lib/index.js'; import KeyDIDResolver from 'key-did-resolver' import {Resolver} from 'did-resolver' @@ -143,29 +145,31 @@ Connected to anchor service '' with supported anchor chains ['inmemory ] ``` -// code snippet for ed25519 + +The code for other curves is similar: + +#### code snippet for ed25519 ``` const doc = await didResolver.resolve('did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8') ``` -// code snippet for P-256 +#### code snippet for P-256 ``` const doc = await didResolver.resolve('did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu') ``` -// code snippet for P-384 +#### code snippet for P-384 ``` const doc = await didResolver.resolve('did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54') ``` -// code snippet for P-521 +#### code snippet for P-521 ``` const doc = await didResolver.resolve('did:key:z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t') ``` +Note: All P-*** curves are compressed -// Note: All P-*** curves are compressed - -// did document verificationMethod for ed25519: +#### did document verificationMethod for ed25519: ``` [ { @@ -177,7 +181,7 @@ const doc = await didResolver.resolve('did:key:z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6 ] ``` -// did document verificationMethod for P-256: +#### did document verificationMethod for P-256: ``` [ { @@ -194,7 +198,7 @@ const doc = await didResolver.resolve('did:key:z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6 ] ``` -// did document verificationMethod for P-384: +#### did document verificationMethod for P-384: ``` [ { @@ -211,7 +215,7 @@ const doc = await didResolver.resolve('did:key:z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6 ] ``` -// did document verificationMethod for P-521: +#### did document verificationMethod for P-521: ``` [ { @@ -227,362 +231,15 @@ const doc = await didResolver.resolve('did:key:z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6 } ] ``` -``` -// Usage from cloned GitHub Repository: -// import * as keyDIDResolver from '../js-ceramic/packages/key-did-resolver/lib/index.js'; - -import keyDIDResolver from 'key-did-resolver' - -const resolverRegistry = keyDIDResolver.getResolver(); - -const resolve = resolverRegistry.key; - -let parsedDided25519 = { - id: "z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8", - did: 'did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8', - method: "key", - didUrl: 'did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8/some/path', - path: '/some/path' -} - -let doced25519 = await resolve('did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8', parsedDided25519, {}, { accept: 'application/did+ld+json' }) - -console.log(); -console.log('did document for ed25519:'); -console.log(doced25519); -console.log(); - -console.log('did document metatdata:'); -console.log(doced25519.didDocument.verificationMethod); - -let parsedDid256k1 = { - id: "zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz", - did: 'did:key:zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz', - method: "key", - didUrl: 'did:key:zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz/some/path', - path: '/some/path' -} - -let doc256k1 = await resolve('did:key:zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz', parsedDid256k1, {}, { accept: 'application/did+ld+json' }) - -console.log(); -console.log('did document for secp256k1:'); -console.log(doc256k1); -console.log(); - -console.log('did document metatdata:'); -console.log(doc256k1.didDocument.verificationMethod); - -let parsedDid256 = { - id: "zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu", - did: 'did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu', - method: "key", - didUrl: 'did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu/some/path', - path: '/some/path' -} - -let doc256 = await resolve('did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu', parsedDid256, {}, { accept: 'application/did+ld+json' }) - -console.log(); -console.log('did document for P-256:'); -console.log(doc256); -console.log(); - -console.log('did document metatdata:'); -console.log(doc256.didDocument.verificationMethod); - -let parsedDid384 = { - id: "z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54", - did: 'did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54', - method: "key", - didUrl: 'did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54/some/path', - path: '/some/path' -} - -let doc384 = await resolve('did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54', parsedDid384, {}, { accept: 'application/did+ld+json' }) - -console.log(); -console.log('did document for P-384:'); -console.log(doc384); -console.log(); - -console.log('did document metatdata:'); -console.log(doc384.didDocument.verificationMethod); - -let parsedDid521 = { - id: "z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t", - did: 'did:key:z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t', - method: "key", - didUrl: 'did:key:z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t/some/path', - path: '/some/path' -} - -let doc521 = await resolve('did:key:z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t', parsedDid521, {}, { accept: 'application/did+ld+json' }) - -console.log(); -console.log('did document for P-521:'); -console.log(doc521) -console.log(); - -console.log('did document metadata:'); -console.log(doc521.didDocument.verificationMethod); - -``` - -### Output -``` -{ - didResolutionMetadata: { contentType: 'application/did+json' }, - didDocument: { - id: 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme', - verificationMethod: [ [Object] ], - authentication: [ - 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme#zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme' - ], - assertionMethod: [ - 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme#zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme' - ], - capabilityDelegation: [ - 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme#zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme' - ], - capabilityInvocation: [ - 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme#zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme' - ] - }, - didDocumentMetadata: {} -} -[ - { - id: 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme#zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme', - type: 'Secp256k1VerificationKey2018', - controller: 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme', - publicKeyBase58: '23o6Sau8NxxzXcgSc3PLcNxrzrZpbLeBn1izfv3jbKhuv' - } -] -``` - -``` -Swarm listening on /ip4/127.0.0.1/tcp/4011/p2p/QmYGmd8VoQ1sZ82diHEzhbPxfrjrxryLMnJem4UaNnEf8K -Swarm listening on /ip4/10.0.0.5/tcp/4011/p2p/QmYGmd8VoQ1sZ82diHEzhbPxfrjrxryLMnJem4UaNnEf8K -Swarm listening on /ip4/127.0.0.1/tcp/4012/ws/p2p/QmYGmd8VoQ1sZ82diHEzhbPxfrjrxryLMnJem4UaNnEf8K -Swarm listening on /ip4/10.0.0.5/tcp/4012/ws/p2p/QmYGmd8VoQ1sZ82diHEzhbPxfrjrxryLMnJem4UaNnEf8K -Connecting to ceramic network 'inmemory' using pubsub topic '/ceramic/inmemory-2974851949' -Peer discovery is not supported for ceramic network: inmemory. This node may fail to load documents from other nodes on the network. -This node with peerId QmYGmd8VoQ1sZ82diHEzhbPxfrjrxryLMnJem4UaNnEf8K is not included in the peer list for Ceramic network inmemory. It will not be discoverable by other nodes in the network, and so data created against this node will not be available to the rest of the network. -Connected to anchor service '' with supported anchor chains ['inmemory:12345'] -{ key: [AsyncFunction: key] } -{ - didResolutionMetadata: { contentType: 'application/did+json' }, - didDocument: { - id: 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme', - verificationMethod: [ [Object] ], - authentication: [ - 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme#zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme' - ], - assertionMethod: [ - 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme#zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme' - ], - capabilityDelegation: [ - 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme#zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme' - ], - capabilityInvocation: [ - 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme#zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme' - ] - }, - didDocumentMetadata: {} -} -[ - { - id: 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme#zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme', - type: 'Secp256k1VerificationKey2018', - controller: 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme', - publicKeyBase58: '23o6Sau8NxxzXcgSc3PLcNxrzrZpbLeBn1izfv3jbKhuv' - } -] -``` - -``` - -did document for ed25519: -{ - didResolutionMetadata: { contentType: 'application/did+ld+json' }, - didDocument: { - id: 'did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8', - verificationMethod: [ [Object] ], - authentication: [ - 'did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8#z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8' - ], - assertionMethod: [ - 'did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8#z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8' - ], - capabilityDelegation: [ - 'did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8#z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8' - ], - capabilityInvocation: [ - 'did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8#z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8' - ], - keyAgreement: [ [Object] ], - '@context': 'https://w3id.org/did/v1' - }, - didDocumentMetadata: {} -} - -did document for secp256k1: -{ - didResolutionMetadata: { contentType: 'application/did+ld+json' }, - didDocument: { - id: 'did:key:zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz', - verificationMethod: [ [Object] ], - authentication: [ - 'did:key:zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz#zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz' - ], - assertionMethod: [ - 'did:key:zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz#zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz' - ], - capabilityDelegation: [ - 'did:key:zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz#zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz' - ], - capabilityInvocation: [ - 'did:key:zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz#zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz' - ], - '@context': 'https://w3id.org/did/v1' - }, - didDocumentMetadata: {} -} - -did document metatdata: -[ - { - id: 'did:key:zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz#zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz', - type: 'Secp256k1VerificationKey2018', - controller: 'did:key:zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz', - publicKeyBase58: 'qjdSRUCiVtAjwdYVTxHQXd9FnMPRaYCtKpkchofTw66G' - } -] - -did document for P-256: -{ - didResolutionMetadata: { contentType: 'application/did+ld+json' }, - didDocument: { - id: 'did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu', - verificationMethod: [ [Object] ], - authentication: [ - 'did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu#zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu' - ], - assertionMethod: [ - 'did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu#zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu' - ], - capabilityDelegation: [ - 'did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu#zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu' - ], - capabilityInvocation: [ - 'did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu#zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu' - ], - '@context': 'https://w3id.org/did/v1' - }, - didDocumentMetadata: {} -} - -did document metadata: -[ - { - id: 'did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu#zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu', - type: 'JsonWebKey2020', - controller: 'did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu', - publicKeyJwk: { - kty: 'EC', - crv: 'P-256', - x: 'OcPddBMXKURtwbPaZ9SfwEb8vwcvzFufpRwFuXQwf5Y', - y: 'nEA7FjXwRJ8CvUInUeMxIaRDTxUvKysqP2dSGcXZJfY' - } - } -] -did document for P-384: -{ - didResolutionMetadata: { contentType: 'application/did+ld+json' }, - didDocument: { - id: 'did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54', - verificationMethod: [ [Object] ], - authentication: [ - 'did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54#z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54' - ], - assertionMethod: [ - 'did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54#z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54' - ], - capabilityDelegation: [ - 'did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54#z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54' - ], - capabilityInvocation: [ - 'did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54#z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54' - ], - '@context': 'https://w3id.org/did/v1' - }, - didDocumentMetadata: {} -} - -did document metadata: -[ - { - id: 'did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54#z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54', - type: 'JsonWebKey2020', - controller: 'did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54', - publicKeyJwk: { - kty: 'EC', - crv: 'P-384', - x: 'CA-iNoHDg1lL8pvX3d1uvExzVfCz7Rn6tW781Ub8K5MrDf2IMPyL0RTDiaLHC1JT', - y: 'Kpnrn8DkXUD3ge4mFxi-DKr0DYO2KuJdwNBrhzLRtfMa3WFMZBiPKUPfJj8dYNl_' - } - } -] - -did document for P-521: -{ - didResolutionMetadata: { contentType: 'application/did+ld+json' }, - didDocument: { - id: 'did:key:z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t', - verificationMethod: [ [Object] ], - authentication: [ - 'did:key:z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t#z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t' - ], - assertionMethod: [ - 'did:key:z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t#z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t' - ], - capabilityDelegation: [ - 'did:key:z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t#z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t' - ], - capabilityInvocation: [ - 'did:key:z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t#z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t' - ], - '@context': 'https://w3id.org/did/v1' - }, - didDocumentMetadata: {} -} - -did document metadata: -[ - { - id: 'did:key:z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t#z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t', - type: 'JsonWebKey2020', - controller: 'did:key:z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t', - publicKeyJwk: { - kty: 'EC', - crv: 'P-521', - x: 'ATkofCC8_KAAJ3XSRayyPk8WqF9qahhoQVjbHtzbe5MSaaFiMKBZr-CurF9IcpJD-YYEukPmarSKFpXLtwAdiONT', - y: 'AWuYkJ7iaFhfz_dzFemaBnuq1WFnoZeIha7KpE9benPTX9FQhAoyHY-2qO4IyqGe1XGGtx8eJXvp57xMtUXm2rAH' - } - } -] - -``` -## Testing +### Testing Due to problems with parsing JSON with BigInt, tests need to be run with Jest in Serial mode. Use **_npm run test -- --runInBand_** . -## Comments +### Comments During development there was not yet consensus on using all compressed keys. Support for uncompressed keys with the '04' prefix and raw keys (just the x,y bytes with no prefix) was kept for the P-256 and P-384 curves. -## References +### References [Standards for Efficient Cryptography SEC 2: Recommended Elliptic Curve Domain Parameters From 4d6ad9676e3c950cb0f803a83b166036f16ea6aa Mon Sep 17 00:00:00 2001 From: Brent Shambaugh Date: Wed, 8 Dec 2021 15:51:13 -0600 Subject: [PATCH 18/38] update the README with some final touches --- packages/key-did-resolver/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/key-did-resolver/README.md b/packages/key-did-resolver/README.md index 70606f94f7..0d1045dc43 100644 --- a/packages/key-did-resolver/README.md +++ b/packages/key-did-resolver/README.md @@ -146,7 +146,7 @@ Connected to anchor service '' with supported anchor chains ['inmemory ``` -The code for other curves is similar: +The code for other curves is similar. Changing the did:key string is sufficient. #### code snippet for ed25519 ``` @@ -169,6 +169,8 @@ const doc = await didResolver.resolve('did:key:z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6 ``` Note: All P-*** curves are compressed +The verification method results are slightly different. Here is a sampling: + #### did document verificationMethod for ed25519: ``` [ From b83cedd615aa4b29e7263698e0da550577bfcdf6 Mon Sep 17 00:00:00 2001 From: Brent Shambaugh Date: Wed, 8 Dec 2021 16:20:05 -0600 Subject: [PATCH 19/38] update readme with new usage paragraph --- packages/key-did-resolver/README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/key-did-resolver/README.md b/packages/key-did-resolver/README.md index 0d1045dc43..86c3f1c8f1 100644 --- a/packages/key-did-resolver/README.md +++ b/packages/key-did-resolver/README.md @@ -7,6 +7,18 @@ $ npm install key-did-resolver ``` ### Usage +This code includes support for the curves Ed25519, Secp256k1, Secp256r1 (P-256), Secp384r1 (P-384), and Secp521r1 (P-521) + +This code follows the test vectors at: +[https://github.com/w3c-ccg/did-method-key/tree/main/test-vectors](https://github.com/w3c-ccg/did-method-key/tree/main/test-vectors) + +This code has been tested with the following did providers: +| Curve | Repositry | +| ------------------- | -------------------------------------------------------------- | +| Ed25519 | https://github.com/ceramicnetwork/key-did-provider-ed25519 | +| Secp256k1 | https://github.com/ceramicnetwork/key-did-provider-secp256k1 | +| P-256, P-384, P-521 | https://github.com/bshambaugh/did-key-creator | + This code includes support for Ed25519 and Secp256k1 did:keys described in https://github.com/w3c-ccg/did-method-key . Example code for creating a did:key for Ed25519 is here: From 113aa4e88a7e42d305bf2e94e59ec64d3621d2a3 Mon Sep 17 00:00:00 2001 From: Brent Shambaugh Date: Wed, 8 Dec 2021 16:22:08 -0600 Subject: [PATCH 20/38] clean up new usage paragraph --- packages/key-did-resolver/README.md | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/packages/key-did-resolver/README.md b/packages/key-did-resolver/README.md index 86c3f1c8f1..6c207fd21b 100644 --- a/packages/key-did-resolver/README.md +++ b/packages/key-did-resolver/README.md @@ -19,14 +19,6 @@ This code has been tested with the following did providers: | Secp256k1 | https://github.com/ceramicnetwork/key-did-provider-secp256k1 | | P-256, P-384, P-521 | https://github.com/bshambaugh/did-key-creator | -This code includes support for Ed25519 and Secp256k1 did:keys described in https://github.com/w3c-ccg/did-method-key . - -Example code for creating a did:key for Ed25519 is here: -https://github.com/ceramicnetwork/key-did-provider-ed25519 - -Example code for creating a did:key for Secp256k1 is here: -https://github.com/ceramicnetwork/key-did-provider-secp256k1 - This code supports compressed forms of P-256, P-384, and P-521 did:keys in concordance with https://github.com/w3c-ccg/did-method-key test-vectors. The did:key id is the multicodec name + the compressed public key expressed as a Uint8Array (byte array) then encoded with base58btc and expressed as a string. @@ -34,9 +26,6 @@ The syntax of a did:key is did:key:id. Compressed keys are the X coordinate of the public key with a prefix that depends on the sign of the Y curve coordinate. The prefix is '02' if even and '03' if odd. -Example code for creating a did:key for P-256, P-384, and P-521 is here: -https://github.com/bshambaugh/did-key-creator - ### Code Using [@ceramicnetwork/core](https://developers.ceramic.network/reference/typescript/modules/_ceramicnetwork_core.html) with secp256k1 did-key: ``` From 6b19122f2fe824cd325246261aa3749a4e2209a6 Mon Sep 17 00:00:00 2001 From: Brent Shambaugh Date: Wed, 8 Dec 2021 16:29:04 -0600 Subject: [PATCH 21/38] reworded and added footnote --- packages/key-did-resolver/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/key-did-resolver/README.md b/packages/key-did-resolver/README.md index 6c207fd21b..e828dd6de9 100644 --- a/packages/key-did-resolver/README.md +++ b/packages/key-did-resolver/README.md @@ -7,7 +7,7 @@ $ npm install key-did-resolver ``` ### Usage -This code includes support for the curves Ed25519, Secp256k1, Secp256r1 (P-256), Secp384r1 (P-384), and Secp521r1 (P-521) +This code includes support for the curves Ed25519, Secp256k1, Secp256r1 (P-256), Secp384r1 (P-384), and Secp521r1 (P-521) . This code follows the test vectors at: [https://github.com/w3c-ccg/did-method-key/tree/main/test-vectors](https://github.com/w3c-ccg/did-method-key/tree/main/test-vectors) @@ -19,7 +19,7 @@ This code has been tested with the following did providers: | Secp256k1 | https://github.com/ceramicnetwork/key-did-provider-secp256k1 | | P-256, P-384, P-521 | https://github.com/bshambaugh/did-key-creator | -This code supports compressed forms of P-256, P-384, and P-521 did:keys in concordance with https://github.com/w3c-ccg/did-method-key test-vectors. +Compressed forms of P-256, P-384, and P-521 are preferred. [^1] The did:key id is the multicodec name + the compressed public key expressed as a Uint8Array (byte array) then encoded with base58btc and expressed as a string. The syntax of a did:key is did:key:id. @@ -239,7 +239,7 @@ The verification method results are slightly different. Here is a sampling: Due to problems with parsing JSON with BigInt, tests need to be run with Jest in Serial mode. Use **_npm run test -- --runInBand_** . ### Comments -During development there was not yet consensus on using all compressed keys. Support for uncompressed keys with the '04' prefix and +[^1]: During development there was not yet consensus on using all compressed keys. Support for uncompressed keys with the '04' prefix and raw keys (just the x,y bytes with no prefix) was kept for the P-256 and P-384 curves. ### References From f0f25dbaa4e448c768f3647f5ef42058948bed1d Mon Sep 17 00:00:00 2001 From: Brent Shambaugh Date: Wed, 8 Dec 2021 16:31:21 -0600 Subject: [PATCH 22/38] reworded and fixed footnote --- packages/key-did-resolver/README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/key-did-resolver/README.md b/packages/key-did-resolver/README.md index e828dd6de9..e03348a98e 100644 --- a/packages/key-did-resolver/README.md +++ b/packages/key-did-resolver/README.md @@ -21,6 +21,9 @@ This code has been tested with the following did providers: Compressed forms of P-256, P-384, and P-521 are preferred. [^1] +[^1]: During development there was not yet consensus on using all compressed keys. Support for uncompressed keys with the '04' prefix and +raw keys (just the x,y bytes with no prefix) was kept for the P-256 and P-384 curves. + The did:key id is the multicodec name + the compressed public key expressed as a Uint8Array (byte array) then encoded with base58btc and expressed as a string. The syntax of a did:key is did:key:id. @@ -238,10 +241,6 @@ The verification method results are slightly different. Here is a sampling: ### Testing Due to problems with parsing JSON with BigInt, tests need to be run with Jest in Serial mode. Use **_npm run test -- --runInBand_** . -### Comments -[^1]: During development there was not yet consensus on using all compressed keys. Support for uncompressed keys with the '04' prefix and -raw keys (just the x,y bytes with no prefix) was kept for the P-256 and P-384 curves. - ### References [Standards for Efficient Cryptography From fdf9061489e56e9fe286c70a282df44c669ad80d Mon Sep 17 00:00:00 2001 From: Brent Shambaugh Date: Wed, 8 Dec 2021 16:35:45 -0600 Subject: [PATCH 23/38] added new footnote --- packages/key-did-resolver/README.md | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/packages/key-did-resolver/README.md b/packages/key-did-resolver/README.md index e03348a98e..4e0ef07c02 100644 --- a/packages/key-did-resolver/README.md +++ b/packages/key-did-resolver/README.md @@ -7,9 +7,7 @@ $ npm install key-did-resolver ``` ### Usage -This code includes support for the curves Ed25519, Secp256k1, Secp256r1 (P-256), Secp384r1 (P-384), and Secp521r1 (P-521) . - -This code follows the test vectors at: +This code includes support for the curves Ed25519, Secp256k1, Secp256r1 (P-256), Secp384r1 (P-384), and Secp521r1 (P-521) which follow the test vectors at: [https://github.com/w3c-ccg/did-method-key/tree/main/test-vectors](https://github.com/w3c-ccg/did-method-key/tree/main/test-vectors) This code has been tested with the following did providers: @@ -19,15 +17,15 @@ This code has been tested with the following did providers: | Secp256k1 | https://github.com/ceramicnetwork/key-did-provider-secp256k1 | | P-256, P-384, P-521 | https://github.com/bshambaugh/did-key-creator | -Compressed forms of P-256, P-384, and P-521 are preferred. [^1] +Compressed[^1] forms of P-256, P-384, and P-521 are preferred. [^2] -[^1]: During development there was not yet consensus on using all compressed keys. Support for uncompressed keys with the '04' prefix and -raw keys (just the x,y bytes with no prefix) was kept for the P-256 and P-384 curves. +[^1]: The did:key id is the multicodec name + the compressed public key expressed as a Uint8Array (byte array) then encoded with base58btc and expressed as a string. + The syntax of a did:key is did:key:id. -The did:key id is the multicodec name + the compressed public key expressed as a Uint8Array (byte array) then encoded with base58btc and expressed as a string. -The syntax of a did:key is did:key:id. + Compressed keys are the X coordinate of the public key with a prefix that depends on the sign of the Y curve coordinate. The prefix is '02' if even and '03' if odd. -Compressed keys are the X coordinate of the public key with a prefix that depends on the sign of the Y curve coordinate. The prefix is '02' if even and '03' if odd. +[^2]: During development there was not yet consensus on using all compressed keys. Support for uncompressed keys with the '04' prefix and +raw keys (just the x,y bytes with no prefix) was kept for the P-256 and P-384 curves. ### Code Using [@ceramicnetwork/core](https://developers.ceramic.network/reference/typescript/modules/_ceramicnetwork_core.html) with secp256k1 did-key: From 1b3b21299f2a7e102957f5610d9dbb35122341c6 Mon Sep 17 00:00:00 2001 From: Brent Shambaugh Date: Wed, 8 Dec 2021 16:39:16 -0600 Subject: [PATCH 24/38] fix typo --- packages/key-did-resolver/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/key-did-resolver/README.md b/packages/key-did-resolver/README.md index 4e0ef07c02..ebd001f6eb 100644 --- a/packages/key-did-resolver/README.md +++ b/packages/key-did-resolver/README.md @@ -20,7 +20,7 @@ This code has been tested with the following did providers: Compressed[^1] forms of P-256, P-384, and P-521 are preferred. [^2] [^1]: The did:key id is the multicodec name + the compressed public key expressed as a Uint8Array (byte array) then encoded with base58btc and expressed as a string. - The syntax of a did:key is did:key:id. + The syntax of a did:key is `did:key:id`. Compressed keys are the X coordinate of the public key with a prefix that depends on the sign of the Y curve coordinate. The prefix is '02' if even and '03' if odd. From f20c98ee52c5ce2d11b45f21548ca0b32053b23c Mon Sep 17 00:00:00 2001 From: Brent Shambaugh Date: Wed, 8 Dec 2021 16:45:41 -0600 Subject: [PATCH 25/38] update README --- packages/key-did-resolver/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/key-did-resolver/README.md b/packages/key-did-resolver/README.md index ebd001f6eb..7e186da007 100644 --- a/packages/key-did-resolver/README.md +++ b/packages/key-did-resolver/README.md @@ -19,8 +19,7 @@ This code has been tested with the following did providers: Compressed[^1] forms of P-256, P-384, and P-521 are preferred. [^2] -[^1]: The did:key id is the multicodec name + the compressed public key expressed as a Uint8Array (byte array) then encoded with base58btc and expressed as a string. - The syntax of a did:key is `did:key:id`. +[^1]: The syntax of a did:key is `did:key:id`. The did:key `id` is the `base58btc string` representation of the `Uint8Array (byte array)` consisting of the `the multicodec name` followed by `the public key {raw,uncompressed,compressed}`. Compressed keys are the X coordinate of the public key with a prefix that depends on the sign of the Y curve coordinate. The prefix is '02' if even and '03' if odd. From 463e1fb09278734692b646082b6541b00084bd9f Mon Sep 17 00:00:00 2001 From: Brent Shambaugh Date: Wed, 8 Dec 2021 16:49:12 -0600 Subject: [PATCH 26/38] added an additional footnote, to make 3 --- packages/key-did-resolver/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/key-did-resolver/README.md b/packages/key-did-resolver/README.md index 7e186da007..98e3ba7788 100644 --- a/packages/key-did-resolver/README.md +++ b/packages/key-did-resolver/README.md @@ -10,20 +10,20 @@ $ npm install key-did-resolver This code includes support for the curves Ed25519, Secp256k1, Secp256r1 (P-256), Secp384r1 (P-384), and Secp521r1 (P-521) which follow the test vectors at: [https://github.com/w3c-ccg/did-method-key/tree/main/test-vectors](https://github.com/w3c-ccg/did-method-key/tree/main/test-vectors) -This code has been tested with the following did providers: +This code has been tested with the following `did:key`[^1] providers: | Curve | Repositry | | ------------------- | -------------------------------------------------------------- | | Ed25519 | https://github.com/ceramicnetwork/key-did-provider-ed25519 | | Secp256k1 | https://github.com/ceramicnetwork/key-did-provider-secp256k1 | | P-256, P-384, P-521 | https://github.com/bshambaugh/did-key-creator | -Compressed[^1] forms of P-256, P-384, and P-521 are preferred. [^2] +Compressed[^2] forms of P-256, P-384, and P-521 are preferred. [^3] [^1]: The syntax of a did:key is `did:key:id`. The did:key `id` is the `base58btc string` representation of the `Uint8Array (byte array)` consisting of the `the multicodec name` followed by `the public key {raw,uncompressed,compressed}`. - Compressed keys are the X coordinate of the public key with a prefix that depends on the sign of the Y curve coordinate. The prefix is '02' if even and '03' if odd. +[^2]: Compressed keys are the X coordinate of the public key with a prefix that depends on the sign of the Y curve coordinate. The prefix is '02' if even and '03' if odd. -[^2]: During development there was not yet consensus on using all compressed keys. Support for uncompressed keys with the '04' prefix and +[^3]: During development there was not yet consensus on using all compressed keys. Support for uncompressed keys with the '04' prefix and raw keys (just the x,y bytes with no prefix) was kept for the P-256 and P-384 curves. ### Code From 5dba8ff6dedceb41cee771a0afbac09834967b72 Mon Sep 17 00:00:00 2001 From: Brent Shambaugh Date: Wed, 8 Dec 2021 17:24:20 -0600 Subject: [PATCH 27/38] update code snippet responses for the correct ids for the verification methods --- packages/key-did-resolver/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/key-did-resolver/README.md b/packages/key-did-resolver/README.md index 98e3ba7788..49f4d091f7 100644 --- a/packages/key-did-resolver/README.md +++ b/packages/key-did-resolver/README.md @@ -188,7 +188,7 @@ The verification method results are slightly different. Here is a sampling: ``` [ { - id: 'did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu', + id: 'did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu#zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu', type: 'JsonWebKey2020', controller: 'did:key:zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu', publicKeyJwk: { @@ -205,7 +205,7 @@ The verification method results are slightly different. Here is a sampling: ``` [ { - id: 'did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54', + id: 'did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54#z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54', type: 'JsonWebKey2020', controller: 'did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54', publicKeyJwk: { @@ -222,7 +222,7 @@ The verification method results are slightly different. Here is a sampling: ``` [ { - id: 'did:key:z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t', + id: 'did:key:z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t#z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t', type: 'JsonWebKey2020', controller: 'did:key:z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t', publicKeyJwk: { From 8007b5c89cae54326978d6128b4255dbcf83811f Mon Sep 17 00:00:00 2001 From: Brent Shambaugh Date: Wed, 8 Dec 2021 21:14:08 -0600 Subject: [PATCH 28/38] use multiformats instead of multibase --- packages/key-did-resolver/package.json | 5 +++-- packages/key-did-resolver/src/index.ts | 6 +++--- .../key-did-resolver/src/nist_weierstrass_common.ts | 11 +++++------ 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/key-did-resolver/package.json b/packages/key-did-resolver/package.json index 935fdfc9ec..7c32c6aca9 100644 --- a/packages/key-did-resolver/package.json +++ b/packages/key-did-resolver/package.json @@ -28,10 +28,11 @@ }, "dependencies": { "@stablelib/ed25519": "^1.0.1", + "bigint-mod-arith": "^3.0.0", "multibase": "~4.0.2", + "multiformats": "^9.5.2", "uint8arrays": "^2.0.5", - "varint": "^6.0.0", - "bigint-mod-arith": "^3.0.0" + "varint": "^6.0.0" }, "devDependencies": { "@types/multibase": "~3.1.0", diff --git a/packages/key-did-resolver/src/index.ts b/packages/key-did-resolver/src/index.ts index 9e315e20c0..9a38fde982 100644 --- a/packages/key-did-resolver/src/index.ts +++ b/packages/key-did-resolver/src/index.ts @@ -1,5 +1,5 @@ import varint from 'varint' -import multibase from 'multibase' +import { base58btc } from 'multiformats/bases/base58' import type { DIDResolutionResult, DIDResolutionOptions, @@ -40,8 +40,8 @@ export function getResolver(): ResolverRegistry { didDocumentMetadata: {}, } try { - const multicodecPubKey: any = multibase.decode(parsed.id) - const keyType = varint.decode(multicodecPubKey) + const multicodecPubKey: any = base58btc.decode(parsed.id) + const keyType = varint.decode(multicodecPubKey) const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) const doc = await prefixToDriverMap[keyType].keyToDidDoc(pubKeyBytes, parsed.id) if (contentType === DID_LD_JSON) { diff --git a/packages/key-did-resolver/src/nist_weierstrass_common.ts b/packages/key-did-resolver/src/nist_weierstrass_common.ts index 6671b3baee..c36497da80 100644 --- a/packages/key-did-resolver/src/nist_weierstrass_common.ts +++ b/packages/key-did-resolver/src/nist_weierstrass_common.ts @@ -1,8 +1,7 @@ // Brent Shambaugh . 2021. import * as u8a from 'uint8arrays' -import multibase from'multibase' -//import * as bigintModArith from 'bigint-mod-arith' +import { base64url } from 'multiformats/bases/base64' /** * x,y point as a BigInt (requires at least ES2020) @@ -57,8 +56,8 @@ export function publicKeyToXY(publicKeyHex: string) : base64urlPoint { throw new TypeError('input must be string with characters 0-9,A-F,a-f'); } const u8aOctetPoint = publicKeyHexToUint8ArrayPointPair(publicKeyHex); - const xm = (u8a.toString(multibase.encode('base64url',u8aOctetPoint.xOctet))).slice(1); - const ym = (u8a.toString(multibase.encode('base64url',u8aOctetPoint.yOctet))).slice(1); + const xm = base64url.encode(u8aOctetPoint.xOctet).slice(1); + const ym = base64url.encode(u8aOctetPoint.yOctet).slice(1); return { xm, ym }; } @@ -131,8 +130,8 @@ export function publicKeyIntToXY(ecpoint: BigIntPoint): base64urlPoint { if(typeof ecpoint.x !== "bigint" && typeof ecpoint.y !== "bigint") { throw new Error("Input coordinates must be BigInt"); } const u8aOctetPoint = publicKeyIntToUint8ArrayPointPair(ecpoint); - const xm = (u8a.toString(multibase.encode('base64url',u8aOctetPoint.xOctet))).slice(1); - const ym = (u8a.toString(multibase.encode('base64url',u8aOctetPoint.yOctet))).slice(1); + const xm = base64url.encode(u8aOctetPoint.xOctet).slice(1); + const ym = base64url.encode(u8aOctetPoint.yOctet).slice(1); return { xm, ym }; } From 9c45f3fcf23204e3958b0cfe6cca470d00ce0107 Mon Sep 17 00:00:00 2001 From: Brent Shambaugh Date: Wed, 8 Dec 2021 22:21:43 -0600 Subject: [PATCH 29/38] update tests to use multiformats instead of multibase --- .../src/__tests__/ed25519.test.ts | 8 +-- .../src/__tests__/secp256k1.test.ts | 8 +-- .../src/__tests__/secp256r1.test.ts | 44 ++++++++-------- .../src/__tests__/secp384r1.test.ts | 52 +++++++++---------- .../src/__tests__/secp521r1.test.ts | 20 +++---- 5 files changed, 66 insertions(+), 66 deletions(-) diff --git a/packages/key-did-resolver/src/__tests__/ed25519.test.ts b/packages/key-did-resolver/src/__tests__/ed25519.test.ts index 6af2344067..730c8cf8e4 100644 --- a/packages/key-did-resolver/src/__tests__/ed25519.test.ts +++ b/packages/key-did-resolver/src/__tests__/ed25519.test.ts @@ -1,5 +1,5 @@ import varint from "varint" -import multibase from "multibase" +import { base58btc } from 'multiformats/bases/base58' import * as mapper from "../ed25519" describe('Ed25519 mapper', () => { @@ -7,9 +7,9 @@ describe('Ed25519 mapper', () => { it('successfully resolves the document from did', async () => { const id = 'z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8' - const multicodecPubKey = multibase.decode(id) - varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well - const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) + const multiformatPubKey = base58btc.decode(id); + varint.decode(multiformatPubKey) // decode is changing param multiformatPubKey as well + const pubKeyBytes = multiformatPubKey.slice(varint.decode.bytes) const doc = await mapper.keyToDidDoc(pubKeyBytes, id) expect(doc).toMatchSnapshot() }) diff --git a/packages/key-did-resolver/src/__tests__/secp256k1.test.ts b/packages/key-did-resolver/src/__tests__/secp256k1.test.ts index 47ec0a8ef4..05fe0137c3 100644 --- a/packages/key-did-resolver/src/__tests__/secp256k1.test.ts +++ b/packages/key-did-resolver/src/__tests__/secp256k1.test.ts @@ -1,5 +1,5 @@ import varint from "varint" -import multibase from "multibase" +import { base58btc } from 'multiformats/bases/base58' import * as mapper from "../secp256k1" describe('Secp256k1 mapper', () => { @@ -7,9 +7,9 @@ describe('Secp256k1 mapper', () => { it('successfully resolves the document from did', async () => { const id = "zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz" - const multicodecPubKey = multibase.decode(id) - varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well - const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) + const multiformatPubKey = base58btc.decode(id); + varint.decode(multiformatPubKey) // decode is changing param multiformatPubKey as well + const pubKeyBytes = multiformatPubKey.slice(varint.decode.bytes) const doc = await mapper.keyToDidDoc(pubKeyBytes, id) expect(doc).toMatchSnapshot() }) diff --git a/packages/key-did-resolver/src/__tests__/secp256r1.test.ts b/packages/key-did-resolver/src/__tests__/secp256r1.test.ts index ad235c54db..9c44ba3f15 100644 --- a/packages/key-did-resolver/src/__tests__/secp256r1.test.ts +++ b/packages/key-did-resolver/src/__tests__/secp256r1.test.ts @@ -1,7 +1,7 @@ // Brent Shambaugh . 2021. import varint from "varint" -import multibase from "multibase" +import { base58btc } from 'multiformats/bases/base58' import * as mapper from "../secp256r1" import * as u8a from 'uint8arrays' @@ -10,9 +10,9 @@ describe('Secp256r1 mapper', () => { it('successfully resolves the document from did:key from raw public key', async () => { const id = "zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ" - const multicodecPubKey = multibase.decode(id) - varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well - const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) + const multiformatPubKey = base58btc.decode(id); + varint.decode(multiformatPubKey) // decode is changing param multiformatPubKey as well + const pubKeyBytes = multiformatPubKey.slice(varint.decode.bytes) const doc = await mapper.keyToDidDoc(pubKeyBytes, id) expect(doc).toMatchSnapshot() }) @@ -20,9 +20,9 @@ describe('Secp256r1 mapper', () => { it('successfully resolves the document from did:key from raw public key #2', async () => { const id = "zrusAFgBbf84b8mBz8Cmy8UoFWKV52EaeRnK86vnLo4Z5QoRypE6hXVPN2urevZMAMtcTaCDFLWBaE1Q3jmdb1FHgve" - const multicodecPubKey = multibase.decode(id) - varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well - const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) + const multiformatPubKey = base58btc.decode(id); + varint.decode(multiformatPubKey) // decode is changing param multiformatPubKey as well + const pubKeyBytes = multiformatPubKey.slice(varint.decode.bytes) const doc = await mapper.keyToDidDoc(pubKeyBytes, id) expect(doc).toMatchSnapshot() }) @@ -30,9 +30,9 @@ describe('Secp256r1 mapper', () => { it('successfully resolves the document from did:key from raw public key #3', async () => { const id = "zrurwcJZss4ruepVNu1H3xmSirvNbzgBk9qrCktB6kaewXnJAhYWwtP3bxACqBpzjZdN7TyHNzzGGSSH5qvZsSDir9z" - const multicodecPubKey = multibase.decode(id) - varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well - const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) + const multiformatPubKey = base58btc.decode(id); + varint.decode(multiformatPubKey) // decode is changing param multiformatPubKey as well + const pubKeyBytes = multiformatPubKey.slice(varint.decode.bytes) const doc = await mapper.keyToDidDoc(pubKeyBytes, id) expect(doc).toMatchSnapshot() }) @@ -40,9 +40,9 @@ describe('Secp256r1 mapper', () => { it('successfully resolves the document from did:key from compressed public key', async () => { const id = "zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu" - const multicodecPubKey = multibase.decode(id) - varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well - const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) + const multiformatPubKey = base58btc.decode(id); + varint.decode(multiformatPubKey) // decode is changing param multiformatPubKey as well + const pubKeyBytes = multiformatPubKey.slice(varint.decode.bytes) const doc = await mapper.keyToDidDoc(pubKeyBytes, id) expect(doc).toMatchSnapshot() }) @@ -50,9 +50,9 @@ describe('Secp256r1 mapper', () => { it('successfully resolves the document from did:key from compressed public key #2', async () => { const id = "zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv" - const multicodecPubKey = multibase.decode(id) - varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well - const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) + const multiformatPubKey = base58btc.decode(id); + varint.decode(multiformatPubKey) // decode is changing param multiformatPubKey as well + const pubKeyBytes = multiformatPubKey.slice(varint.decode.bytes) const doc = await mapper.keyToDidDoc(pubKeyBytes, id) expect(doc).toMatchSnapshot() }) @@ -60,9 +60,9 @@ describe('Secp256r1 mapper', () => { it('successfully resolves the document from did:key from compressed public key #3', async () => { const id = "zDnaerDaTF5BXEavCrfRZEk316dpbLsfPDZ3WJ5hRTPFU2169" - const multicodecPubKey = multibase.decode(id) - varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well - const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) + const multiformatPubKey = base58btc.decode(id); + varint.decode(multiformatPubKey) // decode is changing param multiformatPubKey as well + const pubKeyBytes = multiformatPubKey.slice(varint.decode.bytes) const doc = await mapper.keyToDidDoc(pubKeyBytes, id) expect(doc).toMatchSnapshot() }) @@ -70,9 +70,9 @@ describe('Secp256r1 mapper', () => { it('successfully resolves the document from did:key from uncompressed public key', async () => { const id = "z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY" - const multicodecPubKey = multibase.decode(id) - varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well - const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) + const multiformatPubKey = base58btc.decode(id); + varint.decode(multiformatPubKey) // decode is changing param multiformatPubKey as well + const pubKeyBytes = multiformatPubKey.slice(varint.decode.bytes) const doc = await mapper.keyToDidDoc(pubKeyBytes, id) expect(doc).toMatchSnapshot() }) diff --git a/packages/key-did-resolver/src/__tests__/secp384r1.test.ts b/packages/key-did-resolver/src/__tests__/secp384r1.test.ts index c8acf15570..d43fca6099 100644 --- a/packages/key-did-resolver/src/__tests__/secp384r1.test.ts +++ b/packages/key-did-resolver/src/__tests__/secp384r1.test.ts @@ -1,7 +1,7 @@ // Brent Shambaugh . 2021. import varint from "varint" -import multibase from "multibase" +import { base58btc } from 'multiformats/bases/base58' import * as mapper from "../secp384r1" import * as u8a from 'uint8arrays' @@ -10,9 +10,9 @@ describe('Secp384r1 mapper', () => { it('Secp384r1 mapper successfully resolves the document from did:key from raw public key', async () => { const id = "zFwfeyrSyWdksRYykTGGtagWazFB5zS4CjQcxDMQSNmCTQB5QMqokx2VJz4vBB2hN1nUrYDTuYq3kd1BM5cUCfFD4awiNuzEBuoy6rZZTMCsZsdvWkDXY6832qcAnzE7YGw43KU" - const multicodecPubKey = multibase.decode(id) - varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well - const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) + const multiformatPubKey = base58btc.decode(id); + varint.decode(multiformatPubKey) // decode is changing param multiformatPubKey as well + const pubKeyBytes = multiformatPubKey.slice(varint.decode.bytes) const doc = await mapper.keyToDidDoc(pubKeyBytes, id) expect(doc).toMatchSnapshot() }) @@ -20,9 +20,9 @@ describe('Secp384r1 mapper', () => { it('Secp384r1 mapper successfully resolves the document from did:key from raw public key #2', async () => { const id = "zFwepbBSaPFjt5T1zWptHaXugLNxHYABfJrDoAZRYxKjNkpdfrniF3pvYQAXwxVB7afhmsgzYtSCzTVZQ3F5SPHzP5PuHgtBGNYucZTSrnA7yTTDr7WGQZaTTkJWfiH47jW5ahU" - const multicodecPubKey = multibase.decode(id) - varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well - const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) + const multiformatPubKey = base58btc.decode(id); + varint.decode(multiformatPubKey) // decode is changing param multiformatPubKey as well + const pubKeyBytes = multiformatPubKey.slice(varint.decode.bytes) const doc = await mapper.keyToDidDoc(pubKeyBytes, id) expect(doc).toMatchSnapshot() }) @@ -30,9 +30,9 @@ describe('Secp384r1 mapper', () => { it('Secp384r1 mapper successfully resolves the document from did:key from raw public key #3', async () => { const id = "zFwfwzpxzCAUjJK6X7cLDFjxbp6G3iJy6AcntWLBu5SxJeGBjge7jVkmARyUqkJideMFofkhGF94wLopAmuqCH1JQ3fbzxmrBwKK52qF5w429kUJk5NdR8BJwDxpeWryV4oAH27"; - const multicodecPubKey = multibase.decode(id) - varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well - const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) + const multiformatPubKey = base58btc.decode(id); + varint.decode(multiformatPubKey) // decode is changing param multiformatPubKey as well + const pubKeyBytes = multiformatPubKey.slice(varint.decode.bytes) const doc = await mapper.keyToDidDoc(pubKeyBytes, id) expect(doc).toMatchSnapshot() }) @@ -40,9 +40,9 @@ describe('Secp384r1 mapper', () => { it('Secp384r1 mapper successfully resolves the document from did:key from compressed public key', async () => { const id = "z82Lm1MpAkeJcix9K8TMiLd5NMAhnwkjjCBeWHXyu3U4oT2MVJJKXkcVBgjGhnLBn2Kaau9" - const multicodecPubKey = multibase.decode(id) - varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well - const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) + const multiformatPubKey = base58btc.decode(id); + varint.decode(multiformatPubKey) // decode is changing param multiformatPubKey as well + const pubKeyBytes = multiformatPubKey.slice(varint.decode.bytes) const doc = await mapper.keyToDidDoc(pubKeyBytes, id) expect(doc).toMatchSnapshot() }) @@ -50,9 +50,9 @@ describe('Secp384r1 mapper', () => { it('Secp384r1 mapper successfully resolves the document from did:key from compressed public key #2', async () => { const id = "z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54" - const multicodecPubKey = multibase.decode(id) - varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well - const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) + const multiformatPubKey = base58btc.decode(id); + varint.decode(multiformatPubKey) // decode is changing param multiformatPubKey as well + const pubKeyBytes = multiformatPubKey.slice(varint.decode.bytes) const doc = await mapper.keyToDidDoc(pubKeyBytes, id) expect(doc).toMatchSnapshot() }) @@ -60,9 +60,9 @@ describe('Secp384r1 mapper', () => { it('Secp384r1 mapper successfully resolves the document from did:key from compressed public key #3', async () => { const id = "z82Lm2BuneDPATu4BSWzhZwuandHAwY4DJrv3gAbo8RvG6yBTLJx6AhgoSmKy8XSK4HaPvA" - const multicodecPubKey = multibase.decode(id) - varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well - const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) + const multiformatPubKey = base58btc.decode(id); + varint.decode(multiformatPubKey) // decode is changing param multiformatPubKey as well + const pubKeyBytes = multiformatPubKey.slice(varint.decode.bytes) const doc = await mapper.keyToDidDoc(pubKeyBytes, id) expect(doc).toMatchSnapshot() }) @@ -71,9 +71,9 @@ describe('Secp384r1 mapper', () => { it('successfully resolves the document from did', async () => { const id = "z28xDr9xiQCrXbooH2aC3eMVv74QKvxBgP1DHCMBWz6CvTHmdt4rtsH9JSHGsyPzdQpfMBJSSAHFh1zTjiyLhKchrMnNfBVEtCziwX2yy3YiQY9t6WcVUpSdVHaxeRz5x6JYoGGPJ" - const multicodecPubKey = multibase.decode(id) - varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well - const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) + const multiformatPubKey = base58btc.decode(id); + varint.decode(multiformatPubKey) // decode is changing param multiformatPubKey as well + const pubKeyBytes = multiformatPubKey.slice(varint.decode.bytes) const doc = await mapper.keyToDidDoc(pubKeyBytes, id) expect(doc).toMatchSnapshot() }) @@ -81,10 +81,10 @@ describe('Secp384r1 mapper', () => { // testing the key from the did:key from the uncompressed public key it('successfully resolves the document from did', async () => { const id = "z28xDrNf4RYwmuLQmfFBWWwiaxZtqyfME8BGUHemrsKUn6ShdzCLZWq2ZhmmSpVK2rtSLoeA1CJjrwGjZ64yCjJ9odVTYDdAMSu2LsTL1c5ehyQdkatFonfv3d7VNCByDrqntBoVz"; - - const multicodecPubKey = multibase.decode(id) - varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well - const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) + + const multiformatPubKey = base58btc.decode(id); + varint.decode(multiformatPubKey) // decode is changing param multiformatPubKey as well + const pubKeyBytes = multiformatPubKey.slice(varint.decode.bytes) const doc = await mapper.keyToDidDoc(pubKeyBytes, id) expect(doc).toMatchSnapshot() }) diff --git a/packages/key-did-resolver/src/__tests__/secp521r1.test.ts b/packages/key-did-resolver/src/__tests__/secp521r1.test.ts index 45834c430f..4d2bf75b4e 100644 --- a/packages/key-did-resolver/src/__tests__/secp521r1.test.ts +++ b/packages/key-did-resolver/src/__tests__/secp521r1.test.ts @@ -1,7 +1,7 @@ // Brent Shambaugh . 2021. import varint from "varint" -import multibase from "multibase" +import { base58btc } from 'multiformats/bases/base58' import * as mapper from "../secp521r1" import * as u8a from 'uint8arrays' @@ -11,9 +11,9 @@ describe('Secp521r1 mapper', () => { it('successfully resolves the document from did', async () => { const id = "z2J9gaYhkf4Ax2QA65KkcrSxr8JDSxUBwzFq3jmq5iBroY2tE7s1uohXVqEvALPxbvdzbWWQTtHvTprUdbNFha3HawyPcD9P" - const multicodecPubKey = multibase.decode(id) - varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well - const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) + const multiformatPubKey = base58btc.decode(id); + varint.decode(multiformatPubKey) // decode is changing param multiformatPubKey as well + const pubKeyBytes = multiformatPubKey.slice(varint.decode.bytes) const doc = await mapper.keyToDidDoc(pubKeyBytes, id) expect(doc).toMatchSnapshot() }) @@ -22,9 +22,9 @@ describe('Secp521r1 mapper', () => { it('successfully resolves the document from did', async () => { const id = "z2J9gcGdbo8riFqfRzgo3gjJyFcbNJm75hrnpDrZTNqQQxgNVBTtKndBiKxzGXrAbyw5W88VDbR1B1FvRQNTnSezghqnJ7p6" - const multicodecPubKey = multibase.decode(id) - varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well - const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) + const multiformatPubKey = base58btc.decode(id); + varint.decode(multiformatPubKey) // decode is changing param multiformatPubKey as well + const pubKeyBytes = multiformatPubKey.slice(varint.decode.bytes) const doc = await mapper.keyToDidDoc(pubKeyBytes, id) expect(doc).toMatchSnapshot() }) @@ -34,9 +34,9 @@ describe('Secp521r1 mapper', () => { it('successfully resolves the document from did', async () => { const id = "z2J9gcGTjd3NaNifwmaNZN27xioMAzHHCDBmkuQ552hm9kWrzhUepDCSAhiuRYBj1sSXR1LBxgqh6vasYzc8JhC12FpaNDhT" - const multicodecPubKey = multibase.decode(id) - varint.decode(multicodecPubKey) // decode is changing param multicodecPubKey as well - const pubKeyBytes = multicodecPubKey.slice(varint.decode.bytes) + const multiformatPubKey = base58btc.decode(id); + varint.decode(multiformatPubKey) // decode is changing param multiformatPubKey as well + const pubKeyBytes = multiformatPubKey.slice(varint.decode.bytes) const doc = await mapper.keyToDidDoc(pubKeyBytes, id) expect(doc).toMatchSnapshot() }) From 0935ef19c091154ee751064338d73b4c4f8badca Mon Sep 17 00:00:00 2001 From: Brent Shambaugh Date: Mon, 13 Dec 2021 10:12:15 -0600 Subject: [PATCH 30/38] add more test snapshots for secp521r1 --- .../__snapshots__/secp521r1.test.ts.snap | 128 +++++++++++++++++- .../src/__tests__/secp521r1.test.ts | 43 +++++- 2 files changed, 168 insertions(+), 3 deletions(-) diff --git a/packages/key-did-resolver/src/__tests__/__snapshots__/secp521r1.test.ts.snap b/packages/key-did-resolver/src/__tests__/__snapshots__/secp521r1.test.ts.snap index ebad83dce4..b19a502e28 100644 --- a/packages/key-did-resolver/src/__tests__/__snapshots__/secp521r1.test.ts.snap +++ b/packages/key-did-resolver/src/__tests__/__snapshots__/secp521r1.test.ts.snap @@ -1,6 +1,130 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Secp521r1 mapper successfully resolves the document from did 1`] = ` +Object { + "assertionMethod": Array [ + "did:key:z2J9gaYaTUV4Ps5GYNNMm4nAyj4pGxd3Nh2zyeFjpEy631ZJ3dYfTDZ68GAhYbNuTn2eMAhKd6hhbzfxLn66vrQ6992jCSxX#z2J9gaYaTUV4Ps5GYNNMm4nAyj4pGxd3Nh2zyeFjpEy631ZJ3dYfTDZ68GAhYbNuTn2eMAhKd6hhbzfxLn66vrQ6992jCSxX", + ], + "authentication": Array [ + "did:key:z2J9gaYaTUV4Ps5GYNNMm4nAyj4pGxd3Nh2zyeFjpEy631ZJ3dYfTDZ68GAhYbNuTn2eMAhKd6hhbzfxLn66vrQ6992jCSxX#z2J9gaYaTUV4Ps5GYNNMm4nAyj4pGxd3Nh2zyeFjpEy631ZJ3dYfTDZ68GAhYbNuTn2eMAhKd6hhbzfxLn66vrQ6992jCSxX", + ], + "capabilityDelegation": Array [ + "did:key:z2J9gaYaTUV4Ps5GYNNMm4nAyj4pGxd3Nh2zyeFjpEy631ZJ3dYfTDZ68GAhYbNuTn2eMAhKd6hhbzfxLn66vrQ6992jCSxX#z2J9gaYaTUV4Ps5GYNNMm4nAyj4pGxd3Nh2zyeFjpEy631ZJ3dYfTDZ68GAhYbNuTn2eMAhKd6hhbzfxLn66vrQ6992jCSxX", + ], + "capabilityInvocation": Array [ + "did:key:z2J9gaYaTUV4Ps5GYNNMm4nAyj4pGxd3Nh2zyeFjpEy631ZJ3dYfTDZ68GAhYbNuTn2eMAhKd6hhbzfxLn66vrQ6992jCSxX#z2J9gaYaTUV4Ps5GYNNMm4nAyj4pGxd3Nh2zyeFjpEy631ZJ3dYfTDZ68GAhYbNuTn2eMAhKd6hhbzfxLn66vrQ6992jCSxX", + ], + "id": "did:key:z2J9gaYaTUV4Ps5GYNNMm4nAyj4pGxd3Nh2zyeFjpEy631ZJ3dYfTDZ68GAhYbNuTn2eMAhKd6hhbzfxLn66vrQ6992jCSxX", + "verificationMethod": Array [ + Object { + "controller": "did:key:z2J9gaYaTUV4Ps5GYNNMm4nAyj4pGxd3Nh2zyeFjpEy631ZJ3dYfTDZ68GAhYbNuTn2eMAhKd6hhbzfxLn66vrQ6992jCSxX", + "id": "did:key:z2J9gaYaTUV4Ps5GYNNMm4nAyj4pGxd3Nh2zyeFjpEy631ZJ3dYfTDZ68GAhYbNuTn2eMAhKd6hhbzfxLn66vrQ6992jCSxX#z2J9gaYaTUV4Ps5GYNNMm4nAyj4pGxd3Nh2zyeFjpEy631ZJ3dYfTDZ68GAhYbNuTn2eMAhKd6hhbzfxLn66vrQ6992jCSxX", + "publicKeyJwk": Object { + "crv": "P-521", + "kty": "EC", + "x": "J0LoEVR-DONWXQbGIietbBoWZUtxQU3YCeBIJRBtoNQpVWfZ5Xjxpry-x3TF2HGMhPVJdbtU1bOOXajTLQAlLBA", + "y": "AUekQSvoIkQ9utmhBYe-xlJhSDJwH9BXB9befk2SKz2hrMpvz7JdHe98bZjF1dcBtJjesmn8BcbyMSCV3VYCsSXE", + }, + "type": "JsonWebKey2020", + }, + ], +} +`; + +exports[`Secp521r1 mapper successfully resolves the document from did 2`] = ` +Object { + "assertionMethod": Array [ + "did:key:z2J9gcGTLNfNooB4Mvx7qeEBccSWARJ3y1xjwbMH9A7ra6oq71rD1daVSVm2YmjUZRWJms18QTZXTnhaH5ihiKiVaG52cuAs#z2J9gcGTLNfNooB4Mvx7qeEBccSWARJ3y1xjwbMH9A7ra6oq71rD1daVSVm2YmjUZRWJms18QTZXTnhaH5ihiKiVaG52cuAs", + ], + "authentication": Array [ + "did:key:z2J9gcGTLNfNooB4Mvx7qeEBccSWARJ3y1xjwbMH9A7ra6oq71rD1daVSVm2YmjUZRWJms18QTZXTnhaH5ihiKiVaG52cuAs#z2J9gcGTLNfNooB4Mvx7qeEBccSWARJ3y1xjwbMH9A7ra6oq71rD1daVSVm2YmjUZRWJms18QTZXTnhaH5ihiKiVaG52cuAs", + ], + "capabilityDelegation": Array [ + "did:key:z2J9gcGTLNfNooB4Mvx7qeEBccSWARJ3y1xjwbMH9A7ra6oq71rD1daVSVm2YmjUZRWJms18QTZXTnhaH5ihiKiVaG52cuAs#z2J9gcGTLNfNooB4Mvx7qeEBccSWARJ3y1xjwbMH9A7ra6oq71rD1daVSVm2YmjUZRWJms18QTZXTnhaH5ihiKiVaG52cuAs", + ], + "capabilityInvocation": Array [ + "did:key:z2J9gcGTLNfNooB4Mvx7qeEBccSWARJ3y1xjwbMH9A7ra6oq71rD1daVSVm2YmjUZRWJms18QTZXTnhaH5ihiKiVaG52cuAs#z2J9gcGTLNfNooB4Mvx7qeEBccSWARJ3y1xjwbMH9A7ra6oq71rD1daVSVm2YmjUZRWJms18QTZXTnhaH5ihiKiVaG52cuAs", + ], + "id": "did:key:z2J9gcGTLNfNooB4Mvx7qeEBccSWARJ3y1xjwbMH9A7ra6oq71rD1daVSVm2YmjUZRWJms18QTZXTnhaH5ihiKiVaG52cuAs", + "verificationMethod": Array [ + Object { + "controller": "did:key:z2J9gcGTLNfNooB4Mvx7qeEBccSWARJ3y1xjwbMH9A7ra6oq71rD1daVSVm2YmjUZRWJms18QTZXTnhaH5ihiKiVaG52cuAs", + "id": "did:key:z2J9gcGTLNfNooB4Mvx7qeEBccSWARJ3y1xjwbMH9A7ra6oq71rD1daVSVm2YmjUZRWJms18QTZXTnhaH5ihiKiVaG52cuAs#z2J9gcGTLNfNooB4Mvx7qeEBccSWARJ3y1xjwbMH9A7ra6oq71rD1daVSVm2YmjUZRWJms18QTZXTnhaH5ihiKiVaG52cuAs", + "publicKeyJwk": Object { + "crv": "P-521", + "kty": "EC", + "x": "lAMfJtiinea2OZt3D9asExhRdC2pVvlIOYv8GlgDCXPKTrRa9Af6ln3HsFDRk5hSqQzdKTwQM6tVnMvTL_1R0tQ", + "y": "AXE4bU-iKe8p2hf9wxUVwMV80Mgohap-kw8JdZ1VVL90YgtgKnUCceTAJDMy0KOKOMEssRI-Q_q3A5F4_zkcOtjV", + }, + "type": "JsonWebKey2020", + }, + ], +} +`; + +exports[`Secp521r1 mapper successfully resolves the document from did 3`] = ` +Object { + "assertionMethod": Array [ + "did:key:z2J9gaZDkUkcV4j5nMPp4dzks3vygMwKRSZWg9j7HNYcR5JLRu361LN6TwrBK3r19VisFYUZEGEXhqqffAprjgmVtCwfCUB1#z2J9gaZDkUkcV4j5nMPp4dzks3vygMwKRSZWg9j7HNYcR5JLRu361LN6TwrBK3r19VisFYUZEGEXhqqffAprjgmVtCwfCUB1", + ], + "authentication": Array [ + "did:key:z2J9gaZDkUkcV4j5nMPp4dzks3vygMwKRSZWg9j7HNYcR5JLRu361LN6TwrBK3r19VisFYUZEGEXhqqffAprjgmVtCwfCUB1#z2J9gaZDkUkcV4j5nMPp4dzks3vygMwKRSZWg9j7HNYcR5JLRu361LN6TwrBK3r19VisFYUZEGEXhqqffAprjgmVtCwfCUB1", + ], + "capabilityDelegation": Array [ + "did:key:z2J9gaZDkUkcV4j5nMPp4dzks3vygMwKRSZWg9j7HNYcR5JLRu361LN6TwrBK3r19VisFYUZEGEXhqqffAprjgmVtCwfCUB1#z2J9gaZDkUkcV4j5nMPp4dzks3vygMwKRSZWg9j7HNYcR5JLRu361LN6TwrBK3r19VisFYUZEGEXhqqffAprjgmVtCwfCUB1", + ], + "capabilityInvocation": Array [ + "did:key:z2J9gaZDkUkcV4j5nMPp4dzks3vygMwKRSZWg9j7HNYcR5JLRu361LN6TwrBK3r19VisFYUZEGEXhqqffAprjgmVtCwfCUB1#z2J9gaZDkUkcV4j5nMPp4dzks3vygMwKRSZWg9j7HNYcR5JLRu361LN6TwrBK3r19VisFYUZEGEXhqqffAprjgmVtCwfCUB1", + ], + "id": "did:key:z2J9gaZDkUkcV4j5nMPp4dzks3vygMwKRSZWg9j7HNYcR5JLRu361LN6TwrBK3r19VisFYUZEGEXhqqffAprjgmVtCwfCUB1", + "verificationMethod": Array [ + Object { + "controller": "did:key:z2J9gaZDkUkcV4j5nMPp4dzks3vygMwKRSZWg9j7HNYcR5JLRu361LN6TwrBK3r19VisFYUZEGEXhqqffAprjgmVtCwfCUB1", + "id": "did:key:z2J9gaZDkUkcV4j5nMPp4dzks3vygMwKRSZWg9j7HNYcR5JLRu361LN6TwrBK3r19VisFYUZEGEXhqqffAprjgmVtCwfCUB1#z2J9gaZDkUkcV4j5nMPp4dzks3vygMwKRSZWg9j7HNYcR5JLRu361LN6TwrBK3r19VisFYUZEGEXhqqffAprjgmVtCwfCUB1", + "publicKeyJwk": Object { + "crv": "P-521", + "kty": "EC", + "x": "Ac3d57-5NBNeQ6ZUkSiTwPsP-h2K5GrPLvCkEQD2kmVgZ6BzaHYyDsVBptzB5yS-lb2DahZmNnTeApVum959s5Eo", + "y": "EgGJ0pcidrh5h-V3bgS1zR6NJ-eaoiKkfPwlJVcMCRI5z5ayOSrueM5oMAisimLAD7r_zzDMbtBp8rNG8yMmd2A", + }, + "type": "JsonWebKey2020", + }, + ], +} +`; + +exports[`Secp521r1 mapper successfully resolves the document from did 4`] = ` +Object { + "assertionMethod": Array [ + "did:key:z2J9gaYd3MzVdZSQDj1zqsxv2tLD5Np3oD7G5F5dHbsF7Sbf1ovGkRfFcaUZMSSDKheREWxapez3vzVwkRYvrSMt4PM4Am1z#z2J9gaYd3MzVdZSQDj1zqsxv2tLD5Np3oD7G5F5dHbsF7Sbf1ovGkRfFcaUZMSSDKheREWxapez3vzVwkRYvrSMt4PM4Am1z", + ], + "authentication": Array [ + "did:key:z2J9gaYd3MzVdZSQDj1zqsxv2tLD5Np3oD7G5F5dHbsF7Sbf1ovGkRfFcaUZMSSDKheREWxapez3vzVwkRYvrSMt4PM4Am1z#z2J9gaYd3MzVdZSQDj1zqsxv2tLD5Np3oD7G5F5dHbsF7Sbf1ovGkRfFcaUZMSSDKheREWxapez3vzVwkRYvrSMt4PM4Am1z", + ], + "capabilityDelegation": Array [ + "did:key:z2J9gaYd3MzVdZSQDj1zqsxv2tLD5Np3oD7G5F5dHbsF7Sbf1ovGkRfFcaUZMSSDKheREWxapez3vzVwkRYvrSMt4PM4Am1z#z2J9gaYd3MzVdZSQDj1zqsxv2tLD5Np3oD7G5F5dHbsF7Sbf1ovGkRfFcaUZMSSDKheREWxapez3vzVwkRYvrSMt4PM4Am1z", + ], + "capabilityInvocation": Array [ + "did:key:z2J9gaYd3MzVdZSQDj1zqsxv2tLD5Np3oD7G5F5dHbsF7Sbf1ovGkRfFcaUZMSSDKheREWxapez3vzVwkRYvrSMt4PM4Am1z#z2J9gaYd3MzVdZSQDj1zqsxv2tLD5Np3oD7G5F5dHbsF7Sbf1ovGkRfFcaUZMSSDKheREWxapez3vzVwkRYvrSMt4PM4Am1z", + ], + "id": "did:key:z2J9gaYd3MzVdZSQDj1zqsxv2tLD5Np3oD7G5F5dHbsF7Sbf1ovGkRfFcaUZMSSDKheREWxapez3vzVwkRYvrSMt4PM4Am1z", + "verificationMethod": Array [ + Object { + "controller": "did:key:z2J9gaYd3MzVdZSQDj1zqsxv2tLD5Np3oD7G5F5dHbsF7Sbf1ovGkRfFcaUZMSSDKheREWxapez3vzVwkRYvrSMt4PM4Am1z", + "id": "did:key:z2J9gaYd3MzVdZSQDj1zqsxv2tLD5Np3oD7G5F5dHbsF7Sbf1ovGkRfFcaUZMSSDKheREWxapez3vzVwkRYvrSMt4PM4Am1z#z2J9gaYd3MzVdZSQDj1zqsxv2tLD5Np3oD7G5F5dHbsF7Sbf1ovGkRfFcaUZMSSDKheREWxapez3vzVwkRYvrSMt4PM4Am1z", + "publicKeyJwk": Object { + "crv": "P-521", + "kty": "EC", + "x": "RIvbfcfZLNaNNZZj87hk-mEhA6rEwob5Pj363BLlrexzEGmIqQbyFX9svSFF7H40vfAbpNGjLxx2tmeNG6pOBYE", + "y": "711FNq0Y9fk-DvGKy0tYf7Cxd8wF18xKunAK-jmA8REzXkRmFYrMBQu91FkBqAYhH2iPkQjSDllveUnKtMiprWY", + }, + "type": "JsonWebKey2020", + }, + ], +} +`; + +exports[`Secp521r1 mapper successfully resolves the document from did 5`] = ` Object { "assertionMethod": Array [ "did:key:z2J9gaYhkf4Ax2QA65KkcrSxr8JDSxUBwzFq3jmq5iBroY2tE7s1uohXVqEvALPxbvdzbWWQTtHvTprUdbNFha3HawyPcD9P#z2J9gaYhkf4Ax2QA65KkcrSxr8JDSxUBwzFq3jmq5iBroY2tE7s1uohXVqEvALPxbvdzbWWQTtHvTprUdbNFha3HawyPcD9P", @@ -31,7 +155,7 @@ Object { } `; -exports[`Secp521r1 mapper successfully resolves the document from did 2`] = ` +exports[`Secp521r1 mapper successfully resolves the document from did 6`] = ` Object { "assertionMethod": Array [ "did:key:z2J9gcGdbo8riFqfRzgo3gjJyFcbNJm75hrnpDrZTNqQQxgNVBTtKndBiKxzGXrAbyw5W88VDbR1B1FvRQNTnSezghqnJ7p6#z2J9gcGdbo8riFqfRzgo3gjJyFcbNJm75hrnpDrZTNqQQxgNVBTtKndBiKxzGXrAbyw5W88VDbR1B1FvRQNTnSezghqnJ7p6", @@ -62,7 +186,7 @@ Object { } `; -exports[`Secp521r1 mapper successfully resolves the document from did 3`] = ` +exports[`Secp521r1 mapper successfully resolves the document from did 7`] = ` Object { "assertionMethod": Array [ "did:key:z2J9gcGTjd3NaNifwmaNZN27xioMAzHHCDBmkuQ552hm9kWrzhUepDCSAhiuRYBj1sSXR1LBxgqh6vasYzc8JhC12FpaNDhT#z2J9gcGTjd3NaNifwmaNZN27xioMAzHHCDBmkuQ552hm9kWrzhUepDCSAhiuRYBj1sSXR1LBxgqh6vasYzc8JhC12FpaNDhT", diff --git a/packages/key-did-resolver/src/__tests__/secp521r1.test.ts b/packages/key-did-resolver/src/__tests__/secp521r1.test.ts index 4d2bf75b4e..63f93ad826 100644 --- a/packages/key-did-resolver/src/__tests__/secp521r1.test.ts +++ b/packages/key-did-resolver/src/__tests__/secp521r1.test.ts @@ -7,7 +7,48 @@ import * as u8a from 'uint8arrays' describe('Secp521r1 mapper', () => { - // testing the key from the did:key from the compressed public key + // testing the key from the did:key from the compressed public key + it('successfully resolves the document from did', async () => { + const id = "z2J9gaYaTUV4Ps5GYNNMm4nAyj4pGxd3Nh2zyeFjpEy631ZJ3dYfTDZ68GAhYbNuTn2eMAhKd6hhbzfxLn66vrQ6992jCSxX" + const multiformatPubKey = base58btc.decode(id); + varint.decode(multiformatPubKey) // decode is changing param multiformatPubKey as well + const pubKeyBytes = multiformatPubKey.slice(varint.decode.bytes) + const doc = await mapper.keyToDidDoc(pubKeyBytes, id) + expect(doc).toMatchSnapshot() + }) + + // testing the key from the did:key from the compressed public key + it('successfully resolves the document from did', async () => { + const id = "z2J9gcGTLNfNooB4Mvx7qeEBccSWARJ3y1xjwbMH9A7ra6oq71rD1daVSVm2YmjUZRWJms18QTZXTnhaH5ihiKiVaG52cuAs" + const multiformatPubKey = base58btc.decode(id); + varint.decode(multiformatPubKey) // decode is changing param multiformatPubKey as well + const pubKeyBytes = multiformatPubKey.slice(varint.decode.bytes) + const doc = await mapper.keyToDidDoc(pubKeyBytes, id) + expect(doc).toMatchSnapshot() + }) + + // testing the key from the did:key from the compressed public key + it('successfully resolves the document from did', async () => { + const id = "z2J9gaZDkUkcV4j5nMPp4dzks3vygMwKRSZWg9j7HNYcR5JLRu361LN6TwrBK3r19VisFYUZEGEXhqqffAprjgmVtCwfCUB1" + const multiformatPubKey = base58btc.decode(id); + varint.decode(multiformatPubKey) // decode is changing param multiformatPubKey as well + const pubKeyBytes = multiformatPubKey.slice(varint.decode.bytes) + const doc = await mapper.keyToDidDoc(pubKeyBytes, id) + expect(doc).toMatchSnapshot() + }) + + + // testing the key from the did:key from the compressed public key + it('successfully resolves the document from did', async () => { + const id = "z2J9gaYd3MzVdZSQDj1zqsxv2tLD5Np3oD7G5F5dHbsF7Sbf1ovGkRfFcaUZMSSDKheREWxapez3vzVwkRYvrSMt4PM4Am1z" + const multiformatPubKey = base58btc.decode(id); + varint.decode(multiformatPubKey) // decode is changing param multiformatPubKey as well + const pubKeyBytes = multiformatPubKey.slice(varint.decode.bytes) + const doc = await mapper.keyToDidDoc(pubKeyBytes, id) + expect(doc).toMatchSnapshot() + }) + + // testing the key from the did:key from the compressed public key it('successfully resolves the document from did', async () => { const id = "z2J9gaYhkf4Ax2QA65KkcrSxr8JDSxUBwzFq3jmq5iBroY2tE7s1uohXVqEvALPxbvdzbWWQTtHvTprUdbNFha3HawyPcD9P" From 58e4bb45cb4ee1d58c145b97300775e0f894738c Mon Sep 17 00:00:00 2001 From: Brent Shambaugh Date: Mon, 13 Dec 2021 10:21:14 -0600 Subject: [PATCH 31/38] swap for spaces to make the linter happy --- packages/key-did-resolver/src/__tests__/secp521r1.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/key-did-resolver/src/__tests__/secp521r1.test.ts b/packages/key-did-resolver/src/__tests__/secp521r1.test.ts index 63f93ad826..86cb6a81d5 100644 --- a/packages/key-did-resolver/src/__tests__/secp521r1.test.ts +++ b/packages/key-did-resolver/src/__tests__/secp521r1.test.ts @@ -20,7 +20,7 @@ describe('Secp521r1 mapper', () => { // testing the key from the did:key from the compressed public key it('successfully resolves the document from did', async () => { const id = "z2J9gcGTLNfNooB4Mvx7qeEBccSWARJ3y1xjwbMH9A7ra6oq71rD1daVSVm2YmjUZRWJms18QTZXTnhaH5ihiKiVaG52cuAs" - const multiformatPubKey = base58btc.decode(id); + const multiformatPubKey = base58btc.decode(id); varint.decode(multiformatPubKey) // decode is changing param multiformatPubKey as well const pubKeyBytes = multiformatPubKey.slice(varint.decode.bytes) const doc = await mapper.keyToDidDoc(pubKeyBytes, id) From cb3d4ce867c3cefe2b6de035bd597ae20da39277 Mon Sep 17 00:00:00 2001 From: Brent Shambaugh Date: Mon, 13 Dec 2021 15:01:32 -0600 Subject: [PATCH 32/38] add did-keys for test vectors for P-521 from w3c/ccg --- .../__snapshots__/secp521r1.test.ts.snap | 74 +++++++++++++++++-- .../src/__tests__/secp521r1.test.ts | 20 +++++ 2 files changed, 88 insertions(+), 6 deletions(-) diff --git a/packages/key-did-resolver/src/__tests__/__snapshots__/secp521r1.test.ts.snap b/packages/key-did-resolver/src/__tests__/__snapshots__/secp521r1.test.ts.snap index b19a502e28..299f13d9fb 100644 --- a/packages/key-did-resolver/src/__tests__/__snapshots__/secp521r1.test.ts.snap +++ b/packages/key-did-resolver/src/__tests__/__snapshots__/secp521r1.test.ts.snap @@ -1,6 +1,68 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Secp521r1 mapper successfully resolves the document from did 1`] = ` +Object { + "assertionMethod": Array [ + "did:key:z2J9gcGdb2nEyMDmzQYv2QZQcM1vXktvy1Pw4MduSWxGabLZ9XESSWLQgbuPhwnXN7zP7HpTzWqrMTzaY5zWe6hpzJ2jnw4f#z2J9gcGdb2nEyMDmzQYv2QZQcM1vXktvy1Pw4MduSWxGabLZ9XESSWLQgbuPhwnXN7zP7HpTzWqrMTzaY5zWe6hpzJ2jnw4f", + ], + "authentication": Array [ + "did:key:z2J9gcGdb2nEyMDmzQYv2QZQcM1vXktvy1Pw4MduSWxGabLZ9XESSWLQgbuPhwnXN7zP7HpTzWqrMTzaY5zWe6hpzJ2jnw4f#z2J9gcGdb2nEyMDmzQYv2QZQcM1vXktvy1Pw4MduSWxGabLZ9XESSWLQgbuPhwnXN7zP7HpTzWqrMTzaY5zWe6hpzJ2jnw4f", + ], + "capabilityDelegation": Array [ + "did:key:z2J9gcGdb2nEyMDmzQYv2QZQcM1vXktvy1Pw4MduSWxGabLZ9XESSWLQgbuPhwnXN7zP7HpTzWqrMTzaY5zWe6hpzJ2jnw4f#z2J9gcGdb2nEyMDmzQYv2QZQcM1vXktvy1Pw4MduSWxGabLZ9XESSWLQgbuPhwnXN7zP7HpTzWqrMTzaY5zWe6hpzJ2jnw4f", + ], + "capabilityInvocation": Array [ + "did:key:z2J9gcGdb2nEyMDmzQYv2QZQcM1vXktvy1Pw4MduSWxGabLZ9XESSWLQgbuPhwnXN7zP7HpTzWqrMTzaY5zWe6hpzJ2jnw4f#z2J9gcGdb2nEyMDmzQYv2QZQcM1vXktvy1Pw4MduSWxGabLZ9XESSWLQgbuPhwnXN7zP7HpTzWqrMTzaY5zWe6hpzJ2jnw4f", + ], + "id": "did:key:z2J9gcGdb2nEyMDmzQYv2QZQcM1vXktvy1Pw4MduSWxGabLZ9XESSWLQgbuPhwnXN7zP7HpTzWqrMTzaY5zWe6hpzJ2jnw4f", + "verificationMethod": Array [ + Object { + "controller": "did:key:z2J9gcGdb2nEyMDmzQYv2QZQcM1vXktvy1Pw4MduSWxGabLZ9XESSWLQgbuPhwnXN7zP7HpTzWqrMTzaY5zWe6hpzJ2jnw4f", + "id": "did:key:z2J9gcGdb2nEyMDmzQYv2QZQcM1vXktvy1Pw4MduSWxGabLZ9XESSWLQgbuPhwnXN7zP7HpTzWqrMTzaY5zWe6hpzJ2jnw4f#z2J9gcGdb2nEyMDmzQYv2QZQcM1vXktvy1Pw4MduSWxGabLZ9XESSWLQgbuPhwnXN7zP7HpTzWqrMTzaY5zWe6hpzJ2jnw4f", + "publicKeyJwk": Object { + "crv": "P-521", + "kty": "EC", + "x": "AQgyFy6EwH3_u_KXPw8aTXTY7WSVytmbuJeFpq4U6LipxtSmBJe_jjRzms9qubnwm_fGoHMQlvQ1vzS2YLusR2V0", + "y": "Ab06MCcgoG7dM2I-VppdLV1k3lDoeHMvyYqHVfP05Ep2O7Zu0Qwd6IVzfZi9K0KMDud22wdnGUpUtFukZo0EeO15", + }, + "type": "JsonWebKey2020", + }, + ], +} +`; + +exports[`Secp521r1 mapper successfully resolves the document from did 2`] = ` +Object { + "assertionMethod": Array [ + "did:key:z2J9gaYxrKVpdoG9A4gRnmpnRCcxU6agDtFVVBVdn1JedouoZN7SzcyREXXzWgt3gGiwpoHq7K68X4m32D8HgzG8wv3sY5j7#z2J9gaYxrKVpdoG9A4gRnmpnRCcxU6agDtFVVBVdn1JedouoZN7SzcyREXXzWgt3gGiwpoHq7K68X4m32D8HgzG8wv3sY5j7", + ], + "authentication": Array [ + "did:key:z2J9gaYxrKVpdoG9A4gRnmpnRCcxU6agDtFVVBVdn1JedouoZN7SzcyREXXzWgt3gGiwpoHq7K68X4m32D8HgzG8wv3sY5j7#z2J9gaYxrKVpdoG9A4gRnmpnRCcxU6agDtFVVBVdn1JedouoZN7SzcyREXXzWgt3gGiwpoHq7K68X4m32D8HgzG8wv3sY5j7", + ], + "capabilityDelegation": Array [ + "did:key:z2J9gaYxrKVpdoG9A4gRnmpnRCcxU6agDtFVVBVdn1JedouoZN7SzcyREXXzWgt3gGiwpoHq7K68X4m32D8HgzG8wv3sY5j7#z2J9gaYxrKVpdoG9A4gRnmpnRCcxU6agDtFVVBVdn1JedouoZN7SzcyREXXzWgt3gGiwpoHq7K68X4m32D8HgzG8wv3sY5j7", + ], + "capabilityInvocation": Array [ + "did:key:z2J9gaYxrKVpdoG9A4gRnmpnRCcxU6agDtFVVBVdn1JedouoZN7SzcyREXXzWgt3gGiwpoHq7K68X4m32D8HgzG8wv3sY5j7#z2J9gaYxrKVpdoG9A4gRnmpnRCcxU6agDtFVVBVdn1JedouoZN7SzcyREXXzWgt3gGiwpoHq7K68X4m32D8HgzG8wv3sY5j7", + ], + "id": "did:key:z2J9gaYxrKVpdoG9A4gRnmpnRCcxU6agDtFVVBVdn1JedouoZN7SzcyREXXzWgt3gGiwpoHq7K68X4m32D8HgzG8wv3sY5j7", + "verificationMethod": Array [ + Object { + "controller": "did:key:z2J9gaYxrKVpdoG9A4gRnmpnRCcxU6agDtFVVBVdn1JedouoZN7SzcyREXXzWgt3gGiwpoHq7K68X4m32D8HgzG8wv3sY5j7", + "id": "did:key:z2J9gaYxrKVpdoG9A4gRnmpnRCcxU6agDtFVVBVdn1JedouoZN7SzcyREXXzWgt3gGiwpoHq7K68X4m32D8HgzG8wv3sY5j7#z2J9gaYxrKVpdoG9A4gRnmpnRCcxU6agDtFVVBVdn1JedouoZN7SzcyREXXzWgt3gGiwpoHq7K68X4m32D8HgzG8wv3sY5j7", + "publicKeyJwk": Object { + "crv": "P-521", + "kty": "EC", + "x": "ASUHPMyichQ0QbHZ9ofNx_l4y7luncn5feKLo3OpJ2nSbZoC7mffolj5uy7s6KSKXFmnNWxGJ42IOrjZ47qqwqyS", + "y": "AW9ziIC4ZQQVSNmLlp59yYKrjRY0_VqO-GOIYQ9tYpPraBKUloEId6cI_vynCzlZWZtWpgOM3HPhYEgawQ703RjC", + }, + "type": "JsonWebKey2020", + }, + ], +} +`; + +exports[`Secp521r1 mapper successfully resolves the document from did 3`] = ` Object { "assertionMethod": Array [ "did:key:z2J9gaYaTUV4Ps5GYNNMm4nAyj4pGxd3Nh2zyeFjpEy631ZJ3dYfTDZ68GAhYbNuTn2eMAhKd6hhbzfxLn66vrQ6992jCSxX#z2J9gaYaTUV4Ps5GYNNMm4nAyj4pGxd3Nh2zyeFjpEy631ZJ3dYfTDZ68GAhYbNuTn2eMAhKd6hhbzfxLn66vrQ6992jCSxX", @@ -31,7 +93,7 @@ Object { } `; -exports[`Secp521r1 mapper successfully resolves the document from did 2`] = ` +exports[`Secp521r1 mapper successfully resolves the document from did 4`] = ` Object { "assertionMethod": Array [ "did:key:z2J9gcGTLNfNooB4Mvx7qeEBccSWARJ3y1xjwbMH9A7ra6oq71rD1daVSVm2YmjUZRWJms18QTZXTnhaH5ihiKiVaG52cuAs#z2J9gcGTLNfNooB4Mvx7qeEBccSWARJ3y1xjwbMH9A7ra6oq71rD1daVSVm2YmjUZRWJms18QTZXTnhaH5ihiKiVaG52cuAs", @@ -62,7 +124,7 @@ Object { } `; -exports[`Secp521r1 mapper successfully resolves the document from did 3`] = ` +exports[`Secp521r1 mapper successfully resolves the document from did 5`] = ` Object { "assertionMethod": Array [ "did:key:z2J9gaZDkUkcV4j5nMPp4dzks3vygMwKRSZWg9j7HNYcR5JLRu361LN6TwrBK3r19VisFYUZEGEXhqqffAprjgmVtCwfCUB1#z2J9gaZDkUkcV4j5nMPp4dzks3vygMwKRSZWg9j7HNYcR5JLRu361LN6TwrBK3r19VisFYUZEGEXhqqffAprjgmVtCwfCUB1", @@ -93,7 +155,7 @@ Object { } `; -exports[`Secp521r1 mapper successfully resolves the document from did 4`] = ` +exports[`Secp521r1 mapper successfully resolves the document from did 6`] = ` Object { "assertionMethod": Array [ "did:key:z2J9gaYd3MzVdZSQDj1zqsxv2tLD5Np3oD7G5F5dHbsF7Sbf1ovGkRfFcaUZMSSDKheREWxapez3vzVwkRYvrSMt4PM4Am1z#z2J9gaYd3MzVdZSQDj1zqsxv2tLD5Np3oD7G5F5dHbsF7Sbf1ovGkRfFcaUZMSSDKheREWxapez3vzVwkRYvrSMt4PM4Am1z", @@ -124,7 +186,7 @@ Object { } `; -exports[`Secp521r1 mapper successfully resolves the document from did 5`] = ` +exports[`Secp521r1 mapper successfully resolves the document from did 7`] = ` Object { "assertionMethod": Array [ "did:key:z2J9gaYhkf4Ax2QA65KkcrSxr8JDSxUBwzFq3jmq5iBroY2tE7s1uohXVqEvALPxbvdzbWWQTtHvTprUdbNFha3HawyPcD9P#z2J9gaYhkf4Ax2QA65KkcrSxr8JDSxUBwzFq3jmq5iBroY2tE7s1uohXVqEvALPxbvdzbWWQTtHvTprUdbNFha3HawyPcD9P", @@ -155,7 +217,7 @@ Object { } `; -exports[`Secp521r1 mapper successfully resolves the document from did 6`] = ` +exports[`Secp521r1 mapper successfully resolves the document from did 8`] = ` Object { "assertionMethod": Array [ "did:key:z2J9gcGdbo8riFqfRzgo3gjJyFcbNJm75hrnpDrZTNqQQxgNVBTtKndBiKxzGXrAbyw5W88VDbR1B1FvRQNTnSezghqnJ7p6#z2J9gcGdbo8riFqfRzgo3gjJyFcbNJm75hrnpDrZTNqQQxgNVBTtKndBiKxzGXrAbyw5W88VDbR1B1FvRQNTnSezghqnJ7p6", @@ -186,7 +248,7 @@ Object { } `; -exports[`Secp521r1 mapper successfully resolves the document from did 7`] = ` +exports[`Secp521r1 mapper successfully resolves the document from did 9`] = ` Object { "assertionMethod": Array [ "did:key:z2J9gcGTjd3NaNifwmaNZN27xioMAzHHCDBmkuQ552hm9kWrzhUepDCSAhiuRYBj1sSXR1LBxgqh6vasYzc8JhC12FpaNDhT#z2J9gcGTjd3NaNifwmaNZN27xioMAzHHCDBmkuQ552hm9kWrzhUepDCSAhiuRYBj1sSXR1LBxgqh6vasYzc8JhC12FpaNDhT", diff --git a/packages/key-did-resolver/src/__tests__/secp521r1.test.ts b/packages/key-did-resolver/src/__tests__/secp521r1.test.ts index 86cb6a81d5..ee83303215 100644 --- a/packages/key-did-resolver/src/__tests__/secp521r1.test.ts +++ b/packages/key-did-resolver/src/__tests__/secp521r1.test.ts @@ -7,6 +7,26 @@ import * as u8a from 'uint8arrays' describe('Secp521r1 mapper', () => { + // testing the key from the did:key from the compressed public key + it('successfully resolves the document from did', async () => { + const id = "z2J9gcGdb2nEyMDmzQYv2QZQcM1vXktvy1Pw4MduSWxGabLZ9XESSWLQgbuPhwnXN7zP7HpTzWqrMTzaY5zWe6hpzJ2jnw4f" + const multiformatPubKey = base58btc.decode(id); + varint.decode(multiformatPubKey) // decode is changing param multiformatPubKey as well + const pubKeyBytes = multiformatPubKey.slice(varint.decode.bytes) + const doc = await mapper.keyToDidDoc(pubKeyBytes, id) + expect(doc).toMatchSnapshot() + }) + + // testing the key from the did:key from the compressed public key + it('successfully resolves the document from did', async () => { + const id = "z2J9gaYxrKVpdoG9A4gRnmpnRCcxU6agDtFVVBVdn1JedouoZN7SzcyREXXzWgt3gGiwpoHq7K68X4m32D8HgzG8wv3sY5j7" + const multiformatPubKey = base58btc.decode(id); + varint.decode(multiformatPubKey) // decode is changing param multiformatPubKey as well + const pubKeyBytes = multiformatPubKey.slice(varint.decode.bytes) + const doc = await mapper.keyToDidDoc(pubKeyBytes, id) + expect(doc).toMatchSnapshot() + }) + // testing the key from the did:key from the compressed public key it('successfully resolves the document from did', async () => { const id = "z2J9gaYaTUV4Ps5GYNNMm4nAyj4pGxd3Nh2zyeFjpEy631ZJ3dYfTDZ68GAhYbNuTn2eMAhKd6hhbzfxLn66vrQ6992jCSxX" From a8d4005711f5f877b57934d5347011c544939f27 Mon Sep 17 00:00:00 2001 From: Brent Shambaugh Date: Mon, 13 Dec 2021 15:03:15 -0600 Subject: [PATCH 33/38] replace with only spaces to satisfy linter --- packages/key-did-resolver/src/__tests__/secp521r1.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/key-did-resolver/src/__tests__/secp521r1.test.ts b/packages/key-did-resolver/src/__tests__/secp521r1.test.ts index ee83303215..64795f388c 100644 --- a/packages/key-did-resolver/src/__tests__/secp521r1.test.ts +++ b/packages/key-did-resolver/src/__tests__/secp521r1.test.ts @@ -20,7 +20,7 @@ describe('Secp521r1 mapper', () => { // testing the key from the did:key from the compressed public key it('successfully resolves the document from did', async () => { const id = "z2J9gaYxrKVpdoG9A4gRnmpnRCcxU6agDtFVVBVdn1JedouoZN7SzcyREXXzWgt3gGiwpoHq7K68X4m32D8HgzG8wv3sY5j7" - const multiformatPubKey = base58btc.decode(id); + const multiformatPubKey = base58btc.decode(id); varint.decode(multiformatPubKey) // decode is changing param multiformatPubKey as well const pubKeyBytes = multiformatPubKey.slice(varint.decode.bytes) const doc = await mapper.keyToDidDoc(pubKeyBytes, id) From 7f06180de15d0ebe389cafb3845798ccd490fc34 Mon Sep 17 00:00:00 2001 From: Brent Shambaugh Date: Mon, 24 Jan 2022 17:03:37 -0600 Subject: [PATCH 34/38] change error message in index.test.ts from 'Cannot read property 'keyToDidDoc' of undefined' to 'TypeError: Cannot read property 'keyToDidDoc' of undefined' --- packages/key-did-resolver/src/__tests__/index.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/key-did-resolver/src/__tests__/index.test.ts b/packages/key-did-resolver/src/__tests__/index.test.ts index bd90ceab1a..efd4e7338b 100644 --- a/packages/key-did-resolver/src/__tests__/index.test.ts +++ b/packages/key-did-resolver/src/__tests__/index.test.ts @@ -127,7 +127,7 @@ describe('Exception mapper + default fpr options.accept', () => { didUrl: 'did:key:z6LSeu9HkTHSfLLeUs2nnzUSNedgDUevfNQgQjQC23ZCit6F/some/path', path: '/some/path' } - await expect(resolve('did:key:z6LSeu9HkTHSfLLeUs2nnzUSNedgDUevfNQgQjQC23ZCit6F', parsedDided25519, {}, { accept: 'application/did+ld+json' })).resolves.toEqual({"didDocument": null, "didDocumentMetadata": {}, "didResolutionMetadata": {"contentType": "application/did+ld+json", "error": "invalidDid", "message": "TypeError: Cannot read property 'keyToDidDoc' of undefined"}}) + await expect(resolve('did:key:z6LSeu9HkTHSfLLeUs2nnzUSNedgDUevfNQgQjQC23ZCit6F', parsedDided25519, {}, { accept: 'application/did+ld+json' })).resolves.toEqual({"didDocument": null, "didDocumentMetadata": {}, "didResolutionMetadata": {"contentType": "application/did+ld+json", "error": "invalidDid", "message": "TypeError: Cannot read properties of undefined (reading 'keyToDidDoc')"}}) }) it('expect index.js to throw an error for an unsupported media type', async () => { From 8548feeba119cafa7ff20dfffe4c211b4bb3bc9a Mon Sep 17 00:00:00 2001 From: Brent Shambaugh Date: Mon, 24 Jan 2022 18:19:41 -0600 Subject: [PATCH 35/38] since dagJose does not need to be converted to be used as an ipld format, import directly --- packages/key-did-resolver/README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/key-did-resolver/README.md b/packages/key-did-resolver/README.md index 453f847e30..8d305e97fd 100644 --- a/packages/key-did-resolver/README.md +++ b/packages/key-did-resolver/README.md @@ -40,10 +40,8 @@ import * as IPFS from 'ipfs-core' import dagJose from 'dag-jose' import {convert} from 'blockcodec-to-ipld-format' -const format = convert(dagJose) - const ipfs = await IPFS.create({ - ipld: { formats: [format] }, + ipld: { formats: [dagJose] }, }) const config = {} From 9e64800241f5755bc15d43f7f0b10c8d08db2c05 Mon Sep 17 00:00:00 2001 From: Brent Shambaugh Date: Fri, 4 Feb 2022 17:55:42 -0600 Subject: [PATCH 36/38] update readme to change Usage to Additional Usage Notes for the last section in key-did-resolver readme, update jest to latest version to run test --- packages/key-did-resolver/README.md | 2 +- packages/key-did-resolver/package.json | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/key-did-resolver/README.md b/packages/key-did-resolver/README.md index 8d305e97fd..bf1e9a6a77 100644 --- a/packages/key-did-resolver/README.md +++ b/packages/key-did-resolver/README.md @@ -256,7 +256,7 @@ PUBLICATION, Digital Signature Standard (DSS)], https://nvlpubs.nist.gov/nistpub [Compact representation of an elliptic curve point, Network Working Group, A.J. Jivsov, March 15, 2014], https://tools.ietf.org/id/draft-jivsov-ecc-compact-05.html -## Usage +## Additional Usage Notes See the [ceramic developer site](https://developers.ceramic.network/) for more details about how to use this package. diff --git a/packages/key-did-resolver/package.json b/packages/key-did-resolver/package.json index f86b602b30..c2ce5b5db1 100644 --- a/packages/key-did-resolver/package.json +++ b/packages/key-did-resolver/package.json @@ -35,6 +35,7 @@ "dependencies": { "@stablelib/ed25519": "^1.0.2", "bigint-mod-arith": "^3.0.0", + "jest": "^27.4.0", "multiformats": "^9.5.2", "uint8arrays": "^3.0.0", "varint": "^6.0.0" From df64b35a157e2a0c81c2b23b1725e10cf6751b5d Mon Sep 17 00:00:00 2001 From: Brent Shambaugh Date: Sun, 6 Feb 2022 12:14:58 -0600 Subject: [PATCH 37/38] remove the include of jest in the package.json for the key-did-resolver package --- packages/key-did-resolver/package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/key-did-resolver/package.json b/packages/key-did-resolver/package.json index c2ce5b5db1..f86b602b30 100644 --- a/packages/key-did-resolver/package.json +++ b/packages/key-did-resolver/package.json @@ -35,7 +35,6 @@ "dependencies": { "@stablelib/ed25519": "^1.0.2", "bigint-mod-arith": "^3.0.0", - "jest": "^27.4.0", "multiformats": "^9.5.2", "uint8arrays": "^3.0.0", "varint": "^6.0.0" From 614b4d7d46c95e627c189a1cb69ae92a4bb85dfc Mon Sep 17 00:00:00 2001 From: Brent Shambaugh Date: Wed, 9 Feb 2022 10:19:06 -0600 Subject: [PATCH 38/38] import nistWeierstrassCommon as nist_weierstrass_common.js in (secp256r1,secp384r1,and secp521r1).ts' --- packages/key-did-resolver/src/secp256r1.ts | 2 +- packages/key-did-resolver/src/secp384r1.ts | 2 +- packages/key-did-resolver/src/secp521r1.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/key-did-resolver/src/secp256r1.ts b/packages/key-did-resolver/src/secp256r1.ts index 3a5bc356ff..88b5332669 100644 --- a/packages/key-did-resolver/src/secp256r1.ts +++ b/packages/key-did-resolver/src/secp256r1.ts @@ -3,7 +3,7 @@ import * as u8a from 'uint8arrays' import * as bigintModArith from 'bigint-mod-arith' -import * as nist_weierstrass_common from './nist_weierstrass_common' +import * as nist_weierstrass_common from './nist_weierstrass_common.js' /** * x,y point as a BigInt (requires at least ES2020) diff --git a/packages/key-did-resolver/src/secp384r1.ts b/packages/key-did-resolver/src/secp384r1.ts index 9126f8587e..6bf76677f4 100644 --- a/packages/key-did-resolver/src/secp384r1.ts +++ b/packages/key-did-resolver/src/secp384r1.ts @@ -3,7 +3,7 @@ import * as u8a from 'uint8arrays' import * as bigintModArith from 'bigint-mod-arith' -import * as nist_weierstrass_common from './nist_weierstrass_common' +import * as nist_weierstrass_common from './nist_weierstrass_common.js' /** * x,y point as a BigInt (requires at least ES2020) diff --git a/packages/key-did-resolver/src/secp521r1.ts b/packages/key-did-resolver/src/secp521r1.ts index dbf74c9547..1bfed354eb 100644 --- a/packages/key-did-resolver/src/secp521r1.ts +++ b/packages/key-did-resolver/src/secp521r1.ts @@ -3,7 +3,7 @@ import * as u8a from 'uint8arrays' import * as bigintModArith from 'bigint-mod-arith' -import * as nist_weierstrass_common from './nist_weierstrass_common' +import * as nist_weierstrass_common from './nist_weierstrass_common.js' /** * x,y point as a BigInt (requires at least ES2020)