diff --git a/packages/key-did-resolver/README.md b/packages/key-did-resolver/README.md index 8954885e1a..bf1e9a6a77 100644 --- a/packages/key-did-resolver/README.md +++ b/packages/key-did-resolver/README.md @@ -10,8 +10,253 @@ ``` $ 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) 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) -## Usage +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[^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}`. + +[^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. + +[^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 +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' +import {Ceramic} from '@ceramicnetwork/core' +import * as IPFS from 'ipfs-core' +import dagJose from 'dag-jose' +import {convert} from 'blockcodec-to-ipld-format' + +const ipfs = await IPFS.create({ + ipld: { formats: [dagJose] }, +}) + +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](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' + +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) +``` + +### 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' + } +] + +``` + +The code for other curves is similar. Changing the did:key string is sufficient. + +#### 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 + +The verification method results are slightly different. Here is a sampling: + +#### 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#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#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#z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t', + type: 'JsonWebKey2020', + controller: 'did:key:z2J9gcGhudjgwsDLv4qJVM6DysnsjWRS6ggtCsSYpV9TGxd9WGoE1EkPxdvPcqEs7eLsQA985AGXPuqttPP7WJ5Qdiz27U3t', + publicKeyJwk: { + kty: 'EC', + crv: 'P-521', + x: 'ATkofCC8_KAAJ3XSRayyPk8WqF9qahhoQVjbHtzbe5MSaaFiMKBZr-CurF9IcpJD-YYEukPmarSKFpXLtwAdiONT', + y: 'AWuYkJ7iaFhfz_dzFemaBnuq1WFnoZeIha7KpE9benPTX9FQhAoyHY-2qO4IyqGe1XGGtx8eJXvp57xMtUXm2rAH' + } + } +] +``` + +### Testing +Due to problems with parsing JSON with BigInt, tests need to be run with Jest in Serial mode. Use **_npm run test -- --runInBand_** . + +### 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 + +[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 + +## 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 e0398b9102..f86b602b30 100644 --- a/packages/key-did-resolver/package.json +++ b/packages/key-did-resolver/package.json @@ -34,6 +34,8 @@ }, "dependencies": { "@stablelib/ed25519": "^1.0.2", + "bigint-mod-arith": "^3.0.0", + "multiformats": "^9.5.2", "uint8arrays": "^3.0.0", "varint": "^6.0.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..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 @@ -145,3 +145,378 @@ 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": "-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 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": "-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y", + "y": "HNNnF7isXk_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": "OcPddBMXKURtwbPaZ9SfwEb8vwcvzFufpRwFuXQwf5Y", + "y": "nEA7FjXwRJ8CvUInUeMxIaRDTxUvKysqP2dSGcXZJfY", + }, + "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": "OcPddBMXKURtwbPaZ9SfwEb8vwcvzFufpRwFuXQwf5Y", + "y": "nEA7FjXwRJ8CvUInUeMxIaRDTxUvKysqP2dSGcXZJfY", + }, + "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": "-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 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": "-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", + }, + ], + }, + "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..b405f88337 --- /dev/null +++ b/packages/key-did-resolver/src/__tests__/__snapshots__/secp256r1.test.ts.snap @@ -0,0 +1,218 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Secp256r1 mapper successfully resolves the document from did:key from compressed public key #2 1`] = ` +Object { + "assertionMethod": Array [ + "did:key:zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv#zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv", + ], + "authentication": Array [ + "did:key:zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv#zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv", + ], + "capabilityDelegation": Array [ + "did:key:zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv#zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv", + ], + "capabilityInvocation": Array [ + "did:key:zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv#zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv", + ], + "id": "did:key:zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv", + "verificationMethod": Array [ + Object { + "controller": "did:key:zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv", + "id": "did:key:zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv#zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv", + "publicKeyJwk": Object { + "crv": "P-256", + "kty": "EC", + "x": "igrFmi0whuihKnj9R3Om1SoMph72wUGeFaBbzG2vzns", + "y": "efsX5b10x8yjyrj4ny3pGfLcY7Xby1KzgqOdqnsrJIM", + }, + "type": "JsonWebKey2020", + }, + ], +} +`; + +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", + ], + "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": "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", + }, + ], +} +`; + +exports[`Secp256r1 mapper successfully resolves the document from did:key from uncompressed public key 1`] = ` +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", + }, + ], +} +`; 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..299f13d9fb --- /dev/null +++ b/packages/key-did-resolver/src/__tests__/__snapshots__/secp521r1.test.ts.snap @@ -0,0 +1,280 @@ +// 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", + ], + "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 4`] = ` +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 5`] = ` +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 6`] = ` +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 7`] = ` +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 8`] = ` +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 9`] = ` +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 c68e8cc8f7..53da81836e 100644 --- a/packages/key-did-resolver/src/__tests__/index.test.ts +++ b/packages/key-did-resolver/src/__tests__/index.test.ts @@ -1,6 +1,7 @@ -import * as index from '../index.js' +import index from '../index.js' describe('Index mapper', () => { + it('successfully resolves the document from did', async () => { const resolverRegistry = index.getResolver() expect(resolverRegistry).not.toBeUndefined() @@ -9,51 +10,162 @@ describe('Index mapper', () => { expect(resolve).not.toBeUndefined() let parsedDid = { - id: 'zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz', + id: "zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz", did: 'did:key:zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz', - method: 'key', + method: "key", didUrl: 'did:key:zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz/some/path', - path: '/some/path', + path: '/some/path' } - let doc = await resolve( - 'did:key:zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz', - parsedDid, - {}, - { accept: 'application/did+ld+json' } - ) + let doc = await resolve('did:key:zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz', parsedDid, {}, { accept: 'application/did+ld+json' }) expect(doc).toMatchSnapshot() - doc = await resolve( - 'did:key:zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz', - parsedDid, - {}, - { accept: 'application/did+json' } - ) + doc = await resolve('did:key:zQ3shbgnTGcgBpXPdBjDur3ATMDWhS7aPs6FRFkWR19Lb9Zwz', parsedDid, {}, { accept: 'application/did+json' }) expect(doc).toMatchSnapshot() parsedDid = { - id: 'z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8', + id: "z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8", did: 'did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8', - method: 'key', + method: "key", didUrl: 'did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8/some/path', - path: '/some/path', + path: '/some/path' + } + + doc = await resolve('did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8', parsedDid, {}, { accept: 'application/did+ld+json' }) + expect(doc).toMatchSnapshot() + + 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() + + parsedDid = { + id: "z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY", + did: 'did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY', + method: "key", + didUrl: 'did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY/some/path', + path: '/some/path' } - doc = await resolve( - 'did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8', - parsedDid, - {}, - { accept: 'application/did+ld+json' } - ) + doc = await resolve('did:key:z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY', parsedDid, {}, { accept: 'application/did+ld+json' }) expect(doc).toMatchSnapshot() - doc = await resolve( - 'did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8', - parsedDid, - {}, - { accept: 'application/did+json' } - ) + 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 + 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() + + 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 properties of undefined (reading 'keyToDidDoc')"}}) + }) + + 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 default to DID_JSON for options.accept when there is an unspecified return 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"}})) + + + }) + }) 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 new file mode 100644 index 0000000000..9c44ba3f15 --- /dev/null +++ b/packages/key-did-resolver/src/__tests__/secp256r1.test.ts @@ -0,0 +1,269 @@ +// Brent Shambaugh . 2021. + +import varint from "varint" +import { base58btc } from 'multiformats/bases/base58' +import * as mapper from "../secp256r1" +import * as u8a from 'uint8arrays' + +describe('Secp256r1 mapper', () => { + + it('successfully resolves the document from did:key from raw public key', async () => { + const id = "zruuPojWkzGPb8sVc42f2YxcTXKUTpAUbdrzVovaTBmGGNyK6cGFaA4Kp7SSLKecrxYz8Sc9d77Rss7rayYt1oFCaNJ" + + 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() + }) + + it('successfully resolves the document from did:key from raw public key #2', async () => { + const id = "zrusAFgBbf84b8mBz8Cmy8UoFWKV52EaeRnK86vnLo4Z5QoRypE6hXVPN2urevZMAMtcTaCDFLWBaE1Q3jmdb1FHgve" + + 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() + }) + + it('successfully resolves the document from did:key from raw public key #3', async () => { + const id = "zrurwcJZss4ruepVNu1H3xmSirvNbzgBk9qrCktB6kaewXnJAhYWwtP3bxACqBpzjZdN7TyHNzzGGSSH5qvZsSDir9z" + + 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() + }) + + it('successfully resolves the document from did:key from compressed public key', async () => { + const id = "zDnaeUKTWUXc1HDpGfKbEK31nKLN19yX5aunFd7VK1CUMeyJu" + + 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() + }) + + it('successfully resolves the document from did:key from compressed public key #2', async () => { + const id = "zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv" + + 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() + }) + + it('successfully resolves the document from did:key from compressed public key #3', async () => { + const id = "zDnaerDaTF5BXEavCrfRZEk316dpbLsfPDZ3WJ5hRTPFU2169" + + 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() + }) + + it('successfully resolves the document from did:key from uncompressed public key', async () => { + const id = "z4oJ8emo5e6mGPCUS5wncFZXAyuVzGRyJZvoduwq7FrdZYPd1LZQbDKsp1YAMX8x14zBwy3yHMSpfecJCMDeRFUgFqYsY" + + 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() + }) + +}) + +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 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: '-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y', + ym: 'HNNnF7isXk_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: '-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y', + ym: 'HNNnF7isXk_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: '-cNviWRiM3i9wGjUvOB-0XyPpIb5rAwmE8o8jDBte7Y', + ym: 'HNNnF7isXk_qitI9yNB4PCMY7krXqA224AJq0LByok8' + }; + 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 (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 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 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); +}); +//**** 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__/secp384r1.test.ts b/packages/key-did-resolver/src/__tests__/secp384r1.test.ts new file mode 100644 index 0000000000..d43fca6099 --- /dev/null +++ b/packages/key-did-resolver/src/__tests__/secp384r1.test.ts @@ -0,0 +1,292 @@ +// Brent Shambaugh . 2021. + +import varint from "varint" +import { base58btc } from 'multiformats/bases/base58' +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 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() + }) + + it('Secp384r1 mapper successfully resolves the document from did:key from raw public key #2', async () => { + const id = "zFwepbBSaPFjt5T1zWptHaXugLNxHYABfJrDoAZRYxKjNkpdfrniF3pvYQAXwxVB7afhmsgzYtSCzTVZQ3F5SPHzP5PuHgtBGNYucZTSrnA7yTTDr7WGQZaTTkJWfiH47jW5ahU" + + 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() + }) + + it('Secp384r1 mapper successfully resolves the document from did:key from raw public key #3', async () => { + const id = "zFwfwzpxzCAUjJK6X7cLDFjxbp6G3iJy6AcntWLBu5SxJeGBjge7jVkmARyUqkJideMFofkhGF94wLopAmuqCH1JQ3fbzxmrBwKK52qF5w429kUJk5NdR8BJwDxpeWryV4oAH27"; + + 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() + }) + + it('Secp384r1 mapper successfully resolves the document from did:key from compressed public key', async () => { + const id = "z82Lm1MpAkeJcix9K8TMiLd5NMAhnwkjjCBeWHXyu3U4oT2MVJJKXkcVBgjGhnLBn2Kaau9" + + 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() + }) + + it('Secp384r1 mapper successfully resolves the document from did:key from compressed public key #2', async () => { + const id = "z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54" + + 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() + }) + + it('Secp384r1 mapper successfully resolves the document from did:key from compressed public key #3', async () => { + const id = "z82Lm2BuneDPATu4BSWzhZwuandHAwY4DJrv3gAbo8RvG6yBTLJx6AhgoSmKy8XSK4HaPvA" + + 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 uncompressed public key + it('successfully resolves the document from did', async () => { + const id = "z28xDr9xiQCrXbooH2aC3eMVv74QKvxBgP1DHCMBWz6CvTHmdt4rtsH9JSHGsyPzdQpfMBJSSAHFh1zTjiyLhKchrMnNfBVEtCziwX2yy3YiQY9t6WcVUpSdVHaxeRz5x6JYoGGPJ" + + 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 uncompressed public key + it('successfully resolves the document from did', async () => { + const id = "z28xDrNf4RYwmuLQmfFBWWwiaxZtqyfME8BGUHemrsKUn6ShdzCLZWq2ZhmmSpVK2rtSLoeA1CJjrwGjZ64yCjJ9odVTYDdAMSu2LsTL1c5ehyQdkatFonfv3d7VNCByDrqntBoVz"; + + 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() + }) + + + +}) + +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..64795f388c --- /dev/null +++ b/packages/key-did-resolver/src/__tests__/secp521r1.test.ts @@ -0,0 +1,237 @@ +// Brent Shambaugh . 2021. + +import varint from "varint" +import { base58btc } from 'multiformats/bases/base58' +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 = "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" + 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" + + 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 = "z2J9gcGdbo8riFqfRzgo3gjJyFcbNJm75hrnpDrZTNqQQxgNVBTtKndBiKxzGXrAbyw5W88VDbR1B1FvRQNTnSezghqnJ7p6" + + 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 = "z2J9gcGTjd3NaNifwmaNZN27xioMAzHHCDBmkuQ552hm9kWrzhUepDCSAhiuRYBj1sSXR1LBxgqh6vasYzc8JhC12FpaNDhT" + + 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() + }) + +}) + +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 a1a8d140ba..584191e0c7 100644 --- a/packages/key-did-resolver/src/index.ts +++ b/packages/key-did-resolver/src/index.ts @@ -10,6 +10,9 @@ import type { import * as secp256k1 from './secp256k1.js' import * as ed25519 from './ed25519.js' +import * as secp256r1 from './secp256r1.js' +import * as secp384r1 from './secp384r1.js' +import * as secp521r1 from './secp521r1.js' const DID_LD_JSON = 'application/did+ld+json' const DID_JSON = 'application/did+json' @@ -17,6 +20,9 @@ const DID_JSON = 'application/did+json' const prefixToDriverMap: any = { 0xe7: secp256k1, 0xed: ed25519, + 0x1200: secp256r1, + 0x1201: secp384r1, + 0x1202: secp521r1 } export function getResolver(): ResolverRegistry { @@ -55,3 +61,6 @@ export function getResolver(): ResolverRegistry { }, } } + +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..c36497da80 --- /dev/null +++ b/packages/key-did-resolver/src/nist_weierstrass_common.ts @@ -0,0 +1,161 @@ +// Brent Shambaugh . 2021. + +import * as u8a from 'uint8arrays' +import { base64url } from 'multiformats/bases/base64' + +/** + * 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 = base64url.encode(u8aOctetPoint.xOctet).slice(1); + const ym = base64url.encode(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 = base64url.encode(u8aOctetPoint.xOctet).slice(1); + const ym = base64url.encode(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 new file mode 100644 index 0000000000..88b5332669 --- /dev/null +++ b/packages/key-did-resolver/src/secp256r1.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.js' + +/** + * 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-256", + 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 - 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(!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 + 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 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(!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-256 key + if(bytesCount == 64) { + 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 nist_weierstrass_common.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 nist_weierstrass_common.publicKeyIntToXY(point); + } + } + + throw new Error('Unexpected pubKeyBytes'); +} diff --git a/packages/key-did-resolver/src/secp384r1.ts b/packages/key-did-resolver/src/secp384r1.ts new file mode 100644 index 0000000000..6bf76677f4 --- /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.js' + +/** + * 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..1bfed354eb --- /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.js' + +/** + * 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'); +}