Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to generate DID from seed. #75

Merged
merged 9 commits into from
Jan 4, 2022
17 changes: 11 additions & 6 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,15 @@
### `14.0.0-beta.2` - 2021-08-19

### Added
- Add `driver.getInitial()` method, to explicitly construct a DID Document deterministically, from a cryptonym DID.
- Add `driver.getInitial()` method, to explicitly construct a DID Document
deterministically, from a cryptonym DID.
- Add an optional `seed` param to `generate()` to generate DID documment from
dmitrizagidulin marked this conversation as resolved.
Show resolved Hide resolved
a 32-byte array seed.


### Changed
- **BREAKING**: Replaced axios with @digitalbazaar/http-client. Errors returned directly from http-client do not match the axios API.
- **BREAKING**: Replaced axios with @digitalbazaar/http-client. Errors returned
directly from http-client do not match the axios API.
- Changed API `getTicketServiceProof` to use `@digitalbazaar/http-client`.
- Changed API `sendToAccelerator` to use `@digitalbazaar/http-client`.
- **BREAKING**: API attachInvocationProof now requires the parameter `invocationTarget`.
Expand All @@ -19,7 +24,7 @@
### Changed
- **BREAKING**: Change in `generate()` semantics to support the common un-registered
DID use case. (See the "Upgrading from `<=12.x` section" below, item 1.)
Now, `generate()` now only generates one key, for `capabilityInvocation` but
Now, `generate()` now only generates one key, for `capabilityInvocation` but
also all the other purposes (much like generating a new `did:key` DID).
(Helper libraries are expected to generate other keys before registering the
DID Document on the ledger.)
Expand All @@ -38,7 +43,7 @@
### Upgrading from <=12.x

**1)** DID Document `generate()` method return signature has changed.
Change in `generate()` semantics (as of `v14.0.0-beta.1`). Since we expect using
Change in `generate()` semantics (as of `v14.0.0-beta.1`). Since we expect using
an un-registered Veres One DID to be a common use case, the previous `generate()`
behavior introduced complications, since different keys for each proof purpose
were created by default. Except that, for the case of un-registered DIDs, the
Expand Down Expand Up @@ -69,14 +74,14 @@ public/private key pair instance that is referenced in the DID Document's
`capabilityInvocation` verification relationship.

**2)** Driver `.get()` method has changed -- no longer uses the `forceConstruct`
parameter. Developers are encouraged to use the CachedResolver from
parameter. Developers are encouraged to use the CachedResolver from
https://github.com/digitalbazaar/did-io instead.
`driver.get()` can still be used to fetch either the full DID Document (via
`await driver.get({did})`) or a key document (via `await driver.get({url: keyId})`).

**3)** Check for `.computeKeyId()` usage. It's been renamed to `.computeId()`.

**4)** Validation methods have changed (used by the `did-veres-one` validator
**4)** Validation methods have changed (used by the `did-veres-one` validator
node):

- `didDocument.validateDid({mode})` becomes:
Expand Down
18 changes: 12 additions & 6 deletions lib/VeresOneDriver.js
Original file line number Diff line number Diff line change
Expand Up @@ -196,12 +196,12 @@ class VeresOneDriver {
*/
async generate({
didType = DEFAULT_DID_TYPE, invokeKey, authKey, delegateKey, assertionKey,
keyAgreementKey
keyAgreementKey, seed
} = {}) {
const {mode, cryptoLd, verificationSuite} = this;
return VeresOneDriver.generate({
didType, cryptoLd, verificationSuite, mode, invokeKey, authKey,
delegateKey, assertionKey, keyAgreementKey
delegateKey, assertionKey, keyAgreementKey, seed
});
}

Expand All @@ -223,24 +223,30 @@ class VeresOneDriver {
* @param {LDKeyPair} [options.delegateKey] - Capability delegation key pair.
* @param {LDKeyPair} [options.assertionKey] - Assertion method key pair.
* @param {LDKeyPair} [options.keyAgreementKey] - Key agreement key pair.
*
* @param {Uint8Array} [options.seed] - A 32-byte array seed for a
* deterministic key.
* @returns {Promise<{didDocument: object, keyPairs: Map,
aljones15 marked this conversation as resolved.
Show resolved Hide resolved
* methodFor: Function}>} Resolves with the generated DID Document, along
* with the corresponding key pairs used to generate it.
*/
static async generate({
didType = DEFAULT_DID_TYPE, cryptoLd, mode,
verificationSuite = DEFAULT_VERIFICATION_SUITE,
invokeKey, authKey, delegateKey, assertionKey, keyAgreementKey
invokeKey, authKey, delegateKey, assertionKey, keyAgreementKey, seed
} = {}) {
const cryptoSuiteContexts = new Set();
const keyPairs = new Map();
const keyType = verificationSuite.suite;

// Before we initialize the rest of the keys, we need to compose the DID
// Document `.id` itself, from the capabilityInvocation key pair.
const capabilityInvocationKeyPair = invokeKey ||
await cryptoLd.generate({type: keyType});
let capabilityInvocationKeyPair;
if(seed) {
capabilityInvocationKeyPair = await verificationSuite.generate({seed});
} else {
capabilityInvocationKeyPair = invokeKey ||
await cryptoLd.generate({type: keyType});
dmitrizagidulin marked this conversation as resolved.
Show resolved Hide resolved
}
cryptoSuiteContexts
.add(capabilityInvocationKeyPair.constructor.SUITE_CONTEXT);

Expand Down
18 changes: 18 additions & 0 deletions test/VeresOneDriver.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const {expect} = chai;

const {Ed25519VerificationKey2020} =
require('@digitalbazaar/ed25519-verification-key-2020');
const {randomBytes} = require('crypto');

const {CryptoLD} = require('crypto-ld');
const {VeresOneDriver} = require('..');
Expand Down Expand Up @@ -173,6 +174,23 @@ describe('methods/veres-one', () => {
expect(didDocument.id).to.match(/^did:v1:nym:z.*/);
});

it('should create a DID document from seed', async () => {
const seed = randomBytes(32);
const {didDocument} = await driver.generate({seed});
console.log(JSON.stringify(didDocument, null, 2), 'didDocument');
expect(didDocument).to.have.keys([
'@context', 'id', 'authentication', 'assertionMethod',
'capabilityDelegation', 'capabilityInvocation', 'keyAgreement'
]);
expect(didDocument.id).to.match(/^did:v1:test:nym:z.*/);
expect(didDocument['@context']).to.eql([
'https://www.w3.org/ns/did/v1',
'https://w3id.org/veres-one/v1',
'https://w3id.org/security/suites/ed25519-2020/v1',
'https://w3id.org/security/suites/x25519-2020/v1'
]);
});

it('should generate a cryptonym based DID Document', async () => {
const {didDocument, methodFor, keyPairs} = await driver.generate();

Expand Down