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

Verifying a proof containing a value of "0" fails #252

Closed
TimoGlastra opened this issue Oct 18, 2023 · 0 comments · Fixed by #255
Closed

Verifying a proof containing a value of "0" fails #252

TimoGlastra opened this issue Oct 18, 2023 · 0 comments · Fixed by #255
Assignees

Comments

@TimoGlastra
Copy link
Member

TimoGlastra commented Oct 18, 2023

When verifying a proof containing an attribute with the value "0" it will fail on the verification of the proof with the error:

AnoncredsError: Proof rejected: Encoded Values for "name" are different in RequestedProof "" and CryptoProof "0"
    at NodeJSAnoncreds.handleError (/Users/timo/Developer/Playground/anoncreds-0-test/node_modules/@hyperledger/anoncreds-nodejs/src/NodeJSAnoncreds.ts:51:11)
    at NodeJSAnoncreds.verifyPresentation (/Users/timo/Developer/Playground/anoncreds-0-test/node_modules/@hyperledger/anoncreds-nodejs/src/NodeJSAnoncreds.ts:464:10)
    at Presentation.verify (/Users/timo/Developer/Playground/anoncreds-0-test/node_modules/@hyperledger/anoncreds-shared/src/api/Presentation.ts:147:28)
    at runAnonCredsRs (/Users/timo/Developer/Playground/anoncreds-0-test/src/index.ts:206:31)
    at Object.<anonymous> (/Users/timo/Developer/Playground/anoncreds-0-test/src/index.ts:215:1)
    at Module._compile (node:internal/modules/cjs/loader:1254:14)
    at Module.m._compile (/Users/timo/Developer/Playground/anoncreds-0-test/node_modules/ts-node/src/index.ts:1618:23)
    at Module._extensions..js (node:internal/modules/cjs/loader:1308:10)
    at Object.require.extensions.<computed> [as .ts] (/Users/timo/Developer/Playground/anoncreds-0-test/node_modules/ts-node/src/index.ts:1621:12)
    at Module.load (node:internal/modules/cjs/loader:1117:32) {
  code: 7,
  extra: undefined
}

I've created the following script (using the JS wrapper) that reproduces the error:

JS reproduction
import {
  CredentialDefinition,
  CredentialOffer,
  CredentialRequest,
  LinkSecret,
  Presentation,
  PresentationRequest,
  Credential,
  Schema,
  anoncreds,
} from "@hyperledger/anoncreds-nodejs";


async function runAnonCredsRs() {
  const nonce = anoncreds.generateNonce();

  const presentationRequest = PresentationRequest.fromJson({
    nonce,
    name: "pres_req_1",
    version: "0.1",
    requested_attributes: {
      attr1_referent: {
        name: "name",
        restrictions: [{ cred_def_id: "mock:uri" }],
      },
    },
    requested_predicates: {},
  });

  const schema = Schema.create({
    name: "schema-1",
    issuerId: "mock:uri",
    version: "1",
    attributeNames: ["name"],
  });

  const {
    credentialDefinition,
    keyCorrectnessProof,
    credentialDefinitionPrivate,
  } = CredentialDefinition.create({
    schemaId: "mock:uri",
    issuerId: "mock:uri",
    schema,
    signatureType: "CL",
    tag: "TAG",
  });

  const credentialOffer = CredentialOffer.create({
    schemaId: "mock:uri",
    credentialDefinitionId: "mock:uri",
    keyCorrectnessProof,
  });

  const linkSecret = LinkSecret.create();
  const linkSecretId = "link secret id";

  const { credentialRequestMetadata, credentialRequest } =
    CredentialRequest.create({
      entropy: "entropy",
      credentialDefinition,
      linkSecret,
      linkSecretId,
      credentialOffer,
    });

  const credential = Credential.create({
    credentialDefinition,
    credentialDefinitionPrivate,
    credentialOffer,
    credentialRequest,
    attributeRawValues: { name: "0" },
  });

  const credentialReceived = credential.process({
    credentialDefinition,
    credentialRequestMetadata,
    linkSecret,
  });

  const presentation = Presentation.create({
    presentationRequest,
    credentials: [
      {
        credential: credentialReceived,
      },
    ],
    credentialDefinitions: { "mock:uri": credentialDefinition },
    credentialsProve: [
      {
        entryIndex: 0,
        isPredicate: false,
        referent: "attr1_referent",
        reveal: true,
      },
    ],
    linkSecret,
    schemas: { "mock:uri": schema },
    selfAttest: {},
  });

  const verify = presentation.verify({
    presentationRequest,
    schemas: { ["mock:uri"]: schema },
    credentialDefinitions: { ["mock:uri"]: credentialDefinition },
  });

  console.log(verify);
}

runAnonCredsRs();

If the value is changed to e.g. "10" in the script above, it will succeed.

I've also re-created the same test with the Indy SDK to see if this is behaviour that was inherited from that library. The same flow works fine with the Indy SDK

Indy SDK flow
import * as indySdk from "indy-sdk";

indySdk.setDefaultLogger("trace");

// @ts-ignore
indySdk.setRuntimeConfig({ collect_backtrace: true });

async function runIndySdk() {
  try {
    const id = "test-" + Math.random();
    await indySdk.createWallet({ id }, { key: "test" });
    const wh = await indySdk.openWallet({ id }, { key: "test" });

    const [did, verkey] = await indySdk.createAndStoreMyDid(wh, {});

    const schema = await indySdk.issuerCreateSchema(did, "schema-1", "1", [
      "name",
    ]);

    const [credDefId, credDefJson] =
      await indySdk.issuerCreateAndStoreCredentialDef(
        wh,
        did,
        schema[1],
        "TAG",
        "CL",
        { support_revocation: false }
      );

    const nonce = await indySdk.generateNonce();

    const credOffer = await indySdk.issuerCreateCredentialOffer(wh, credDefId);

    const masterSecretId = await indySdk.proverCreateMasterSecret(wh, "test");
    const [credReq, credReqMetadata] = await indySdk.proverCreateCredentialReq(
      wh,
      did,
      credOffer,
      credDefJson,
      masterSecretId
    );

    const cred = await indySdk.issuerCreateCredential(
      wh,
      credOffer,
      credReq,
      { name: { encoded: "0", raw: "0" } },
      null,
      -1
    );

    const pr = {
      nonce,
      name: "pres_req_1",
      version: "0.1",
      requested_attributes: {
        attr_ref_1: {
          name: "name",
          restrictions: [{ cred_def_id: credDefId }],
        },
      },
      requested_predicates: {},
    };

    const credId = await indySdk.proverStoreCredential(
      wh,
      null,
      credReqMetadata,
      cred[0],
      credDefJson,
      null
    );
    const proof = await indySdk.proverCreateProof(
      wh,
      pr,
      {
        requested_attributes: {
          attr_ref_1: {
            cred_id: credId,
            revealed: true,
          },
        },
        requested_predicates: {},
        self_attested_attributes: {},
      },
      masterSecretId,
      { [schema[0]]: schema[1] },
      { [credDefId]: credDefJson },
      {}
    );

    const valid = await indySdk.verifierVerifyProof(
      pr,
      proof,
      { [schema[0]]: schema[1] },
      { [credDefId]: credDefJson },
      {},
      {}
    );
    console.log(valid);
  } catch (error) {
    console.error(error);
  }
}

runIndySdk()

I haven't checked if this is also the case using credx, but curious to know if someone (@berendsliedrecht @andrewwhitehead ) knows whats going on here?

It should be supported it seems to include a value of 0? It seems to work fine with a predicate. (so requesting that the value is e.g. >= 0).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants