Skip to content

Commit

Permalink
Move DID Document proof outside metadata (#728)
Browse files Browse the repository at this point in the history
* move proof outside metadata

* remove proof from bindings

* update proof in method spec

* create new document example in method spec
  • Loading branch information
abdulmth authored Mar 18, 2022
1 parent 81e0f25 commit bc6e24d
Show file tree
Hide file tree
Showing 9 changed files with 49 additions and 72 deletions.
31 changes: 12 additions & 19 deletions bindings/wasm/docs/api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,8 @@ publishing to the Tangle.
* [.updateDocumentUnchecked(document)](#Account+updateDocumentUnchecked) ⇒ <code>Promise.&lt;void&gt;</code>
* [.fetchState()](#Account+fetchState) ⇒ <code>Promise.&lt;void&gt;</code>
* [.deleteMethod(options)](#Account+deleteMethod) ⇒ <code>Promise.&lt;void&gt;</code>
* [.createService(options)](#Account+createService) ⇒ <code>Promise.&lt;void&gt;</code>
* [.createMethod(options)](#Account+createMethod) ⇒ <code>Promise.&lt;void&gt;</code>
* [.createService(options)](#Account+createService) ⇒ <code>Promise.&lt;void&gt;</code>
* [.attachMethodRelationships(options)](#Account+attachMethodRelationships) ⇒ <code>Promise.&lt;void&gt;</code>
* [.detachMethodRelationships(options)](#Account+detachMethodRelationships) ⇒ <code>Promise.&lt;void&gt;</code>

Expand Down Expand Up @@ -368,27 +368,27 @@ Deletes a verification method if the method exists.
| --- | --- |
| options | <code>DeleteMethodOptions</code> |

<a name="Account+createService"></a>
<a name="Account+createMethod"></a>

### account.createService(options) ⇒ <code>Promise.&lt;void&gt;</code>
Adds a new Service to the DID Document.
### account.createMethod(options) ⇒ <code>Promise.&lt;void&gt;</code>
Adds a new verification method to the DID document.

**Kind**: instance method of [<code>Account</code>](#Account)

| Param | Type |
| --- | --- |
| options | <code>CreateServiceOptions</code> |
| options | <code>CreateMethodOptions</code> |

<a name="Account+createMethod"></a>
<a name="Account+createService"></a>

### account.createMethod(options) ⇒ <code>Promise.&lt;void&gt;</code>
Adds a new verification method to the DID document.
### account.createService(options) ⇒ <code>Promise.&lt;void&gt;</code>
Adds a new Service to the DID Document.

**Kind**: instance method of [<code>Account</code>](#Account)

| Param | Type |
| --- | --- |
| options | <code>CreateMethodOptions</code> |
| options | <code>CreateServiceOptions</code> |

<a name="Account+attachMethodRelationships"></a>

Expand Down Expand Up @@ -1388,7 +1388,7 @@ Deserializes a `DiffMessage` from a JSON object.
* [.setMetadataUpdated(timestamp)](#Document+setMetadataUpdated)
* [.metadataPreviousMessageId()](#Document+metadataPreviousMessageId) ⇒ <code>string</code>
* [.setMetadataPreviousMessageId(value)](#Document+setMetadataPreviousMessageId)
* [.metadataProof()](#Document+metadataProof) ⇒ <code>any</code>
* [.proof()](#Document+proof) ⇒ <code>any</code>
* [.toJSON()](#Document+toJSON) ⇒ <code>any</code>
* [.clone()](#Document+clone)[<code>Document</code>](#Document)
* _static_
Expand Down Expand Up @@ -1843,9 +1843,9 @@ Sets the previous integration chain message id.
| --- | --- |
| value | <code>string</code> |

<a name="Document+metadataProof"></a>
<a name="Document+proof"></a>

### document.metadataProof() ⇒ <code>any</code>
### document.proof() ⇒ <code>any</code>
Returns a copy of the `proof` object.

**Kind**: instance method of [<code>Document</code>](#Document)
Expand Down Expand Up @@ -2011,7 +2011,6 @@ Additional attributes related to an IOTA DID Document.
* [.previousMessageId](#DocumentMetadata+previousMessageId) ⇒ <code>string</code>
* [.created()](#DocumentMetadata+created)[<code>Timestamp</code>](#Timestamp)
* [.updated()](#DocumentMetadata+updated)[<code>Timestamp</code>](#Timestamp)
* [.proof()](#DocumentMetadata+proof) ⇒ <code>any</code>
* [.clone()](#DocumentMetadata+clone)[<code>DocumentMetadata</code>](#DocumentMetadata)

<a name="DocumentMetadata+previousMessageId"></a>
Expand All @@ -2029,12 +2028,6 @@ Returns a copy of the timestamp of when the DID document was created.
### documentMetadata.updated() ⇒ [<code>Timestamp</code>](#Timestamp)
Returns a copy of the timestamp of the last DID document update.

**Kind**: instance method of [<code>DocumentMetadata</code>](#DocumentMetadata)
<a name="DocumentMetadata+proof"></a>

### documentMetadata.proof() ⇒ <code>any</code>
Returns a copy of the reference to the `proof`.

**Kind**: instance method of [<code>DocumentMetadata</code>](#DocumentMetadata)
<a name="DocumentMetadata+clone"></a>

Expand Down
8 changes: 4 additions & 4 deletions bindings/wasm/src/did/wasm_document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -646,10 +646,10 @@ impl WasmDocument {
}

/// Returns a copy of the `proof` object.
#[wasm_bindgen(js_name = metadataProof)]
pub fn metadata_proof(&self) -> Result<JsValue> {
// TODO: implement proper bindings for the proof
match &self.0.metadata.proof {
#[wasm_bindgen]
pub fn proof(&self) -> Result<JsValue> {
// TODO: implement proper bindings for the proof.
match &self.0.proof {
Some(proof) => JsValue::from_serde(proof).wasm_result(),
None => Ok(JsValue::NULL),
}
Expand Down
11 changes: 0 additions & 11 deletions bindings/wasm/src/did/wasm_document_metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ use identity::iota_core::IotaDocumentMetadata;
use wasm_bindgen::prelude::*;

use crate::common::WasmTimestamp;
use crate::error::Result;
use crate::error::WasmResult;

// =============================================================================
// =============================================================================
Expand Down Expand Up @@ -36,15 +34,6 @@ impl WasmDocumentMetadata {
pub fn previous_message_id(&self) -> String {
self.0.previous_message_id.to_string()
}

/// Returns a copy of the reference to the `proof`.
#[wasm_bindgen]
pub fn proof(&self) -> Result<JsValue> {
match &self.0.proof {
Some(proof) => JsValue::from_serde(proof).wasm_result(),
None => Ok(JsValue::NULL),
}
}
}

impl_wasm_clone!(WasmDocumentMetadata, DocumentMetadata);
Expand Down
27 changes: 13 additions & 14 deletions documentation/docs/specs/did/iota_did_method_spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,32 +113,31 @@ An Integration (Int) DID message MUST contain both a valid DID Document and a [D
* The first DID Document in the chain MUST contain a `verificationMethod` that contains a public key that, when hashed using the `Blake2b-256` hashing function, equals the tag section of the DID. This prevents the creation of conflicting entry messages of the chain by adversaries.
* An Integration DID message must be published to an IOTA Tangle on an index that is generated by the `BLAKE2b-256` of the public key, created in the [generation](#generation) event, encoded in `hex`.
* Integration DID messages SHOULD contain all cumulative changes from the Diff Chain associated to the last Integration Chain message. Any changes added in the Diff Chain that are not added to the new Integration DID message will be lost.
* The DID Document Metadata MUST include at least the following attributes:
* `previousMessageId` (REQUIRED): This field provides an immutable link to the previous integration DID message that is used for basic ordering of the DID messages, creating a chain. The value of `previousMessageId` MUST be a string that contains an IOTA MessageId from the previous DID message it updates, which MUST reference an integration DID message. The field SHOULD be omitted if the DID message is the start of the Int chain, otherwise the field is REQUIRED. Read the [Previous Message Id](#previous-message-id) section for more information.
* `proof` (REQUIRED): This field provides a cryptographic proof on the message that proves ownership over the DID Document. The value of the `proof` object MUST contain an object as defined by [Anatomy of the Proof object](#anatomy-of-the-proof-object).
* The DID Document Metadata MUST include a `previousMessageId` attribute. This field provides an immutable link to the previous integration DID message that is used for basic ordering of the DID messages, creating a chain. The value of `previousMessageId` MUST be a string that contains an IOTA MessageId from the previous DID message it updates, which MUST reference an integration DID message. The field SHOULD be omitted if the DID message is the start of the Int chain, otherwise the field is REQUIRED. Read the [Previous Message Id](#previous-message-id) section for more information.
* The DID Document MUST include a `proof` attribute. This field provides a cryptographic proof on the message that proves ownership over the DID Document. The value of the `proof` object MUST contain an object as defined by [Anatomy of the Proof object](#anatomy-of-the-proof-object).

Example of an Integration DID Message:
```json
{
"doc": {
"id": "did:iota:X7U84ez4YeaLwpfdnhdgFyPLa53twvAuMSYdRQas54e",
"id": "did:iota:ERtmNv3hYnWU7fZMGKpMLy7QBJqPovCSYyewtoHUGmpf",
"capabilityInvocation": [
{
"id": "did:iota:X7U84ez4YeaLwpfdnhdgFyPLa53twvAuMSYdRQas54e#sign-0",
"controller": "did:iota:X7U84ez4YeaLwpfdnhdgFyPLa53twvAuMSYdRQas54e",
"id": "did:iota:ERtmNv3hYnWU7fZMGKpMLy7QBJqPovCSYyewtoHUGmpf#sign-0",
"controller": "did:iota:ERtmNv3hYnWU7fZMGKpMLy7QBJqPovCSYyewtoHUGmpf",
"type": "Ed25519VerificationKey2018",
"publicKeyMultibase": "zCqNmbG7e4GMohTndkStNXUQGHFD5YusnwWpFdpyWFWH3"
"publicKeyMultibase": "zETX79R6G5fkTMZhHXaCMhjC3Xpx3NLJVSNurat8Ls9Tn"
}
]
},
"meta": {
"created": "2022-01-21T09:50:09Z",
"updated": "2022-01-21T09:50:09Z",
"proof": {
"type": "JcsEd25519Signature2020",
"verificationMethod": "#sign-0",
"signatureValue": "4pzMWzn19oqibHXqEdLr4EEHygs7QF2mMdvEhSMPiCVejEZGL4Vi5BGnmrJjMqKyNr6c6sSd3EXKoYxAuC2YiZNF"
}
"created": "2022-03-18T06:59:50Z",
"updated": "2022-03-18T06:59:50Z"
},
"proof": {
"type": "JcsEd25519Signature2020",
"verificationMethod": "did:iota:ERtmNv3hYnWU7fZMGKpMLy7QBJqPovCSYyewtoHUGmpf#sign-0",
"signatureValue": "278R6WyoG359VjnGm2GJK6XAjBNh6AM59BXJmjfRQerVQMTG3EjWGXw64CKgGKvVBbP98QMVUw1YXBbuGuDbJW6A"
}
}
```
Expand Down
6 changes: 4 additions & 2 deletions identity-iota-core/src/diff/diff_iota_document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ impl Diff for IotaDocument {
.transpose()?
.unwrap_or_else(|| self.metadata.clone());

Ok(IotaDocument::from((document, metadata)))
// NOTE: proof intentionally excluded
Ok(IotaDocument::from((document, metadata, None)))
}

fn from_diff(diff: Self::Type) -> Result<Self> {
Expand All @@ -71,7 +72,8 @@ impl Diff for IotaDocument {
.transpose()?
.ok_or_else(|| Error::convert("Missing field `metadata`"))?;

Ok(IotaDocument::from((document, metadata)))
// NOTE: proof intentionally excluded
Ok(IotaDocument::from((document, metadata, None)))
}

fn into_diff(self) -> Result<Self::Type> {
Expand Down
2 changes: 0 additions & 2 deletions identity-iota-core/src/diff/diff_iota_document_metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ impl Diff for IotaDocumentMetadata {
created,
updated,
previous_message_id,
proof: None, // NOTE: proof intentionally excluded.
properties,
})
}
Expand Down Expand Up @@ -130,7 +129,6 @@ impl Diff for IotaDocumentMetadata {
created,
updated,
previous_message_id,
proof: None, // NOTE: proof intentionally excluded.
properties,
})
}
Expand Down
22 changes: 14 additions & 8 deletions identity-iota-core/src/document/iota_document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ pub struct IotaDocument {
pub(crate) document: IotaCoreDocument,
#[serde(rename = "meta")]
pub metadata: IotaDocumentMetadata,
#[serde(skip_serializing_if = "Option::is_none")]
pub proof: Option<Signature>,
}

impl TryMethod for IotaDocument {
Expand Down Expand Up @@ -160,7 +162,7 @@ impl IotaDocument {
.capability_invocation(MethodRef::Embed(method))
.build()?;
let metadata: IotaDocumentMetadata = IotaDocumentMetadata::new();
Ok(Self::from((document, metadata)))
Ok(Self::from((document, metadata, None)))
}

/// Returns whether the given [`MethodType`] can be used to sign document updates.
Expand Down Expand Up @@ -616,9 +618,13 @@ impl IotaDocument {

impl<'a, 'b, 'c> IotaDocument {}

impl From<(IotaCoreDocument, IotaDocumentMetadata)> for IotaDocument {
fn from((document, metadata): (IotaCoreDocument, IotaDocumentMetadata)) -> Self {
Self { document, metadata }
impl From<(IotaCoreDocument, IotaDocumentMetadata, Option<Signature>)> for IotaDocument {
fn from((document, metadata, proof): (IotaCoreDocument, IotaDocumentMetadata, Option<Signature>)) -> Self {
Self {
document,
metadata,
proof,
}
}
}

Expand All @@ -636,19 +642,19 @@ impl Display for IotaDocument {

impl TrySignature for IotaDocument {
fn signature(&self) -> Option<&Signature> {
self.metadata.proof.as_ref()
self.proof.as_ref()
}
}

impl TrySignatureMut for IotaDocument {
fn signature_mut(&mut self) -> Option<&mut Signature> {
self.metadata.proof.as_mut()
self.proof.as_mut()
}
}

impl SetSignature for IotaDocument {
fn set_signature(&mut self, signature: Signature) {
self.metadata.proof = Some(signature)
self.proof = Some(signature)
}
}

Expand Down Expand Up @@ -724,7 +730,7 @@ mod tests {
.build()
.unwrap();

IotaDocument::from((document, metadata))
IotaDocument::from((document, metadata, None))
}

fn generate_testkey() -> KeyPair {
Expand Down
5 changes: 1 addition & 4 deletions identity-iota-core/src/document/iota_document_metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use core::fmt::Result as FmtResult;
use identity_core::common::Object;
use identity_core::common::Timestamp;
use identity_core::convert::FmtJson;
use identity_core::crypto::Signature;

use serde::Deserialize;
use serde::Serialize;

Expand All @@ -27,8 +27,6 @@ pub struct IotaDocumentMetadata {
skip_serializing_if = "MessageId::is_null"
)]
pub previous_message_id: MessageId,
#[serde(skip_serializing_if = "Option::is_none")]
pub proof: Option<Signature>,
#[serde(flatten)]
pub properties: Object,
}
Expand All @@ -42,7 +40,6 @@ impl IotaDocumentMetadata {
created: now,
updated: now,
previous_message_id: MessageId::null(),
proof: None,
properties: Object::default(),
}
}
Expand Down
9 changes: 1 addition & 8 deletions identity-iota/src/chain/document_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,14 +200,7 @@ mod test {
keys.push(keypair);

assert_eq!(
chain
.current()
.document
.metadata
.proof
.as_ref()
.unwrap()
.verification_method(),
chain.current().document.proof.as_ref().unwrap().verification_method(),
format!("#{}", IotaDocument::DEFAULT_METHOD_FRAGMENT)
);
assert_eq!(chain.current().diff_message_id, MessageId::null());
Expand Down

0 comments on commit bc6e24d

Please sign in to comment.