Coder Social home page Coder Social logo

Comments (9)

OR13 avatar OR13 commented on July 20, 2024

In particular https://github.com/decentralized-identity/sidetree-core/blob/master/docs/protocol.md#did-document-resolution

https://github.com/decentralized-identity/sidetree-core/blob/814b67ba6ce5e0a46bc104c115891bf30f202343/tests/RequestHandler.spec.ts#L197

Per the terminology:
Operation hash | The hash of the JSON-formatted request of a Sidetree operation.

Should be base64Url(sha256(bufferFromBase64Url( base64UrlEncodedOp ... or

base64Url(sha256(bufferFromBase64Url( base64UrlEncodedOpPayload ...

Its very confusing to call the base64url encoded sha256 hash of the operation payload json "the operation hash", because its not actually the hash of the operation.

I suggest the operation hash remain named, "Operation hash", and be base64Url of sha256 of bufferFromBase64Url of the base64UrlEncodedOperation... and the spec be updated.

IMO the create is wrong not the update.

Alternatively "Operation Hash" could be renamed to "Operation Payload Hash", but it seems like not a good direction to go. ..The point of the opHash is to compare with previousOperations, not previous operation payloads...

  const operationHash = base64url.encode(
    crypto
      .createHash("sha256")
      .update(base64url.toBuffer(batchFile.operations[0]))
      .digest()
  );

vs

  const operationPayloadHash = base64url.encode(
    crypto
      .createHash("sha256")
      .update(base64url.toBuffer(operation.payload))
      .digest()
  );

Here is what a first update looks like today:


const createPayloadTemplate = {
  "@context": "https://w3id.org/did/v1",
  publicKey: [
    {
      id: "#key1",
      type: "Secp256k1VerificationKey2018",
      publicKeyHex:
        "034ee0f670fc96bb75e8b89c068a1665007a41c98513d6a911b6137e2d16f1d300"
    }
  ]
};

const updatePayloadTemplate = {
  did: "did:sidetree:EiDFDFUSgoxlZoxSlu-17yz_FmMCIx4hpSareCE7IRZv0A",
  operationNumber: 1,
  previousOperationHash: "EiDFDFUSgoxlZoxSlu-17yz_FmMCIx4hpSareCE7IRZv0A",
  patch: [
    {
      op: "replace",
      path: "/publicKey/1",
      value: {
        id: "#key2",
        type: "Secp256k1VerificationKey2018",
        publicKeyHex:
          "029a4774d543094deaf342663ae672728e12f03b3b6d9816b0b79995fade0fab23"
      }
    }
  ]
};
{
  "header": {
    "operation": "create",
    "kid": "#key1",
    "alg": "ES256K",
    "proofOfWork": { }
  },
  "payload": "eyJAY29udGV4dCI6Imh0dHBzOi8vdzNpZC5vcmcvZGlkL3YxIiwicHVibGljS2V5IjpbeyJpZCI6IiNrZXkxIiwidHlwZSI6IlNlY3AyNTZrMVZlcmlmaWNhdGlvbktleTIwMTgiLCJwdWJsaWNLZXlIZXgiOiIwMmY0OTgwMmZiM2UwOWM2ZGQ0M2YxOWFhNDEyOTNkMWUwZGFkMDQ0YjY4Y2Y4MWNmNzA3OTQ5OWVkZmQwYWE5ZjEifSx7ImlkIjoiI2tleTIiLCJ0eXBlIjoiUnNhVmVyaWZpY2F0aW9uS2V5MjAxOCIsInB1YmxpY0tleVBlbSI6Ii0tLS0tQkVHSU4gUFVCTElDIEtFWS4yLkVORCBQVUJMSUMgS0VZLS0tLS0ifV0sInNlcnZpY2UiOlt7InR5cGUiOiJJZGVudGl0eUh1YiIsInB1YmxpY0tleSI6IiNrZXkxIiwic2VydmljZUVuZHBvaW50Ijp7IkBjb250ZXh0Ijoic2NoZW1hLmlkZW50aXR5LmZvdW5kYXRpb24vaHViIiwiQHR5cGUiOiJVc2VyU2VydmljZUVuZHBvaW50IiwiaW5zdGFuY2VzIjpbImRpZDpiYXI6NDU2IiwiZGlkOnphejo3ODkiXX19XX0",
  "signature": "mAJp4ZHwY5UMA05OEKvoZreRo0XrYe77s3RLyGKArG85IoBULs4cLDBtdpOToCtSZhPvCC2xOUXMGyGXDmmEHg"
}

By hashing only the payload, the signature, and header are not being linked to the next operation... Seems clearer to have the operation chain be:

signedOp -> signedOp, instead of signedOp -> signedOp.payload

from sidetree.

thehenrytsai avatar thehenrytsai commented on July 20, 2024

Adding @csuwildcat.

@OR13 You are absolutely spot on with your observation. Up until recently the operation hash has always been the hash of the entire operation request buffer, however, @csuwildcat made a feedback saying that it would be desirable for the operation requester to know the operation hash (thus requester's DID) before the request is sent to a Sidetree node, even if proofOfWork is not included, and hence the change in operation hash definition.

We considered security implications of hashing operation payload directly as operation hash and it seem fine, and it has the benefit of the first operation hash (of a create operation) being exactly the newly created DID, thus reducing a level of indirection.

But I totally agree with you that then it should have been called "operation payload hash" for clarity, so if you agree that this is the right approach, I will create an issue to make sure the rename happens.

from sidetree.

OR13 avatar OR13 commented on July 20, 2024

from sidetree.

thehenrytsai avatar thehenrytsai commented on July 20, 2024

@OR13 Just to be absolutely clear, I take it that your point is to keep operation hash concept away from deterministic DID right?

ie:
first operation hash will NOT be the DID.

Sounds very resonable, I will discuss with @csuwildcat and @arvinda et all and update the create operation hash and spec accordingly.

from sidetree.

OR13 avatar OR13 commented on July 20, 2024

from sidetree.

csuwildcat avatar csuwildcat commented on July 20, 2024

@OR13 one concern I have about moving to the operation hash being the composition of the entirety of operation props/values is that it may lock in the user or writer into having to sequentially assemble/generate each operation, serializing the process, including any future POW additions. The case I was considering was one where a user has an 'unpublished' pairwise DID that they want to cast to the chain for whatever reason - let's say its a scenario where they need the chain to act as the definitive oracle. If they had to quickly publish multiple ops at the same time, they (or the writer) would have to do all the processing one after another. I am not sure how much of an issue this is, but I am weary of creating a condition where a potential downside exists without much upside, know what I mean?

from sidetree.

OR13 avatar OR13 commented on July 20, 2024

from sidetree.

OR13 avatar OR13 commented on July 20, 2024

After discussions in Slack, we think that the previousOperationHash should remain the base64Url(sha256(operation.payload)), this means the previousOperationHash is really just the previousOperationPayloadHash, but the name will remain the same. https://github.com/decentralized-identity/sidetree-core/blob/master/docs/protocol.md#terminology Should be updated to make this clearer, possibly with examples.

from sidetree.

thehenrytsai avatar thehenrytsai commented on July 20, 2024

Fixed in a598104, closing.

from sidetree.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.