Skip to content

Commit

Permalink
Rename prover methods, extend test test_generate_self_attested_proof (#…
Browse files Browse the repository at this point in the history
…764)

* Rename prover & verifier methods, extend test test_generate_self_attested_proof
---------

Signed-off-by: Patrik Stas <patrik.stas@absa.africa>
  • Loading branch information
Patrik-Stas authored Mar 8, 2023
1 parent 7a0d3ee commit 516bdb9
Show file tree
Hide file tree
Showing 27 changed files with 653 additions and 410 deletions.
19 changes: 10 additions & 9 deletions agents/node/vcxagent-core/demo/faber.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,30 +111,31 @@ async function runFaber (options) {
}

logger.info('#27 Process the proof provided by alice.')
const { proofState, proof } = await vcxProof.getProof()
logger.info(`#27 Proof: proofState=${proofState}, proof=${proof}`)
assert(proofState)
assert(proof)
const presentation = vcxProof.getPresentationMsg()
const verificationState = vcxProof.getPresentationVerificationStatus()
logger.info(`#27 Proof: proofState=${verificationState}, proof=${presentation}`)
assert(verificationState)
assert(presentation)
logger.info(`Proof protocol state = ${JSON.stringify(proofProtocolState)}`)
logger.info(`Proof verification state =${proofState}`)
logger.debug(`Proof presentation = ${JSON.stringify(proof, null, 2)}`)
logger.info(`Proof verification state =${verificationState}`)
logger.debug(`Proof presentation = ${JSON.stringify(presentation, null, 2)}`)
logger.debug(`Serialized Proof state machine ${JSON.stringify(await vcxProof.serialize())}`)

if (proofState === ProofState.Verified) {
if (verificationState === ProofState.Verified) {
if (options.revocation) {
throw Error('Proof was verified, but was expected to be invalid, because revocation was enabled.')
} else {
logger.info('Proof was verified.')
}
} else if (proofState === ProofState.Invalid) {
} else if (verificationState === ProofState.Invalid) {
if (options.revocation) {
logger.info('Proof was determined as invalid, which was expected because the used credential was revoked.')
} else {
throw Error('Proof was invalid, but was expected to be verified. Revocation was not enabled.')
}
await sleepPromise(1000)
} else {
logger.error(`Unexpected proof state '${proofState}'.`)
logger.error(`Unexpected proof state '${verificationState}'.`)
process.exit(-1)
}

Expand Down
17 changes: 10 additions & 7 deletions agents/node/vcxagent-core/src/agent.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
const { getLedgerAuthorAgreement, setActiveTxnAuthorAgreementMeta, defaultLogger } = require('@hyperledger/node-vcx-wrapper')
const {
getLedgerAuthorAgreement,
setActiveTxnAuthorAgreementMeta
} = require('@hyperledger/node-vcx-wrapper')
const { createServiceLedgerCredDef } = require('./services/service-ledger-creddef')
const { createServiceLedgerSchema } = require('./services/service-ledger-schema')
const { createServiceVerifier } = require('./services/service-verifier')
Expand All @@ -21,7 +24,7 @@ const {
const { createStorageService } = require('./storage/storage-service')
const { waitUntilAgencyIsReady, getAgencyConfig } = require('./common')

async function createVcxAgent({ agentName, genesisPath, agencyUrl, seed, walletExtraConfigs, endpointInfo, logger }) {
async function createVcxAgent ({ agentName, genesisPath, agencyUrl, seed, walletExtraConfigs, endpointInfo, logger }) {
genesisPath = genesisPath || `${__dirname}/../resources/docker.txn`

await waitUntilAgencyIsReady(agencyUrl, logger)
Expand All @@ -35,7 +38,7 @@ async function createVcxAgent({ agentName, genesisPath, agencyUrl, seed, walletE
const agentProvision = await storageService.loadAgentProvision()
const issuerDid = agentProvision.issuerConfig.institution_did

async function agentInitVcx() {
async function agentInitVcx () {
logger.info(`Initializing ${agentName} vcx session.`)

logger.silly(`Using following agent provision to initialize VCX settings ${JSON.stringify(agentProvision, null, 2)}`)
Expand All @@ -49,17 +52,17 @@ async function createVcxAgent({ agentName, genesisPath, agencyUrl, seed, walletE
await openMainPool({ genesis_path: genesisPath })
}

async function agentShutdownVcx() {
async function agentShutdownVcx () {
logger.debug(`Shutting down ${agentName} vcx session.`)
shutdownVcx()
}

async function updateWebhookUrl(webhookUrl) {
async function updateWebhookUrl (webhookUrl) {
logger.info(`Updating webhook url to ${webhookUrl}`)
await vcxUpdateWebhookUrl({ webhookUrl })
}

async function acceptTaa() {
async function acceptTaa () {
const taa = await getLedgerAuthorAgreement()
const taaJson = JSON.parse(taa)
const utime = Math.floor(new Date() / 1000)
Expand All @@ -68,7 +71,7 @@ async function createVcxAgent({ agentName, genesisPath, agencyUrl, seed, walletE
await setActiveTxnAuthorAgreementMeta(taaJson.text, taaJson.version, null, acceptanceMechanism, utime)
}

function getInstitutionDid() {
function getInstitutionDid () {
return issuerDid
}

Expand Down
5 changes: 0 additions & 5 deletions agents/node/vcxagent-core/src/services/service-prover.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,6 @@ module.exports.createServiceProver = function createServiceProver ({ logger, loa
}
}

async function getVcxDisclosedProof (disclosedProofId) {
logger.warn('Usage of getVcxDisclosedProof is not recommended. You should use vcxagent-core API rather than work with vcx object directly.')
return loadDisclosedProof(disclosedProofId)
}

return {
generateProof,
selectCredentials,
Expand Down
26 changes: 22 additions & 4 deletions agents/node/vcxagent-core/src/services/service-verifier.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,24 @@ module.exports.createServiceVerifier = function createServiceVerifier ({ logger,
return await proof.getState()
}

async function getProofState (proofId) {
async function getPresentationMsg (proofId) {
const proof = await loadProof(proofId)
const { proofState } = await proof.getProof()
return proofState
return JSON.parse(proof.getPresentationMsg())
}

async function getPresentationAttachment (proofId) {
const proof = await loadProof(proofId)
return JSON.parse(proof.getPresentationAttachment())
}

async function getPresentationRequestAttachment (proofId) {
const proof = await loadProof(proofId)
return JSON.parse(proof.getPresentationRequestAttachment())
}

async function getPresentationVerificationStatus (proofId) {
const proof = await loadProof(proofId)
return JSON.parse(proof.getPresentationVerificationStatus())
}

async function listIds () {
Expand Down Expand Up @@ -84,6 +98,10 @@ module.exports.createServiceVerifier = function createServiceVerifier ({ logger,
listIds,
printInfo,
getState,
getProofState

getPresentationMsg,
getPresentationAttachment,
getPresentationRequestAttachment,
getPresentationVerificationStatus
}
}
14 changes: 8 additions & 6 deletions agents/node/vcxagent-core/test/distribute-tails.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ const uuid = require('uuid')
const sleep = require('sleep-promise')
const fs = require('fs')
const mkdirp = require('mkdirp')
const path = require('path')
const { proofRequestDataStandard } = require('./utils/data')

beforeAll(async () => {
jest.setTimeout(1000 * 60 * 4)
Expand All @@ -24,7 +26,7 @@ describe('test tails distribution', () => {
const port = 5468
const tailsUrlId = uuid.v4()
const tailsUrl = `http://127.0.0.1:${port}/${tailsUrlId}`
await faber.buildLedgerPrimitives(buildRevocationDetails({ supportRevocation: true, tailsDir: `${__dirname}/tmp/faber/tails`, maxCreds: 5, tailsUrl }))
await faber.buildLedgerPrimitives(buildRevocationDetails({ supportRevocation: true, tailsDir: path.join(__dirname, '/tmp/faber/tails'), maxCreds: 5, tailsUrl }))
await faber.sendCredentialOffer()
await alice.acceptCredentialOffer()
await faber.updateStateCredential(IssuerStateType.RequestReceived)
Expand All @@ -33,20 +35,20 @@ describe('test tails distribution', () => {

const faberTailsHash = await faber.getTailsHash()
const app = express()
app.use(`/${tailsUrlId}`, express.static(`${__dirname}/tmp/faber/tails/${faberTailsHash}`))
app.use(`/${tailsUrlId}`, express.static(path.join(__dirname, `/tmp/faber/tails/${faberTailsHash}`)))
server = app.listen(port)

const aliceTailsLocation = await alice.getTailsLocation()
const aliceTailsHash = await alice.getTailsHash()
const aliceTailsFileDir = `${__dirname}/tmp/alice/tails`
const aliceTailsFileDir = path.join(__dirname, '/tmp/alice/tails')
const aliceTailsFilePath = aliceTailsFileDir + `/${aliceTailsHash}`
await mkdirp(aliceTailsFileDir)
axios.default.get(`${aliceTailsLocation}`, { responseType: 'stream' }).then(res => {
res.data.pipe(fs.createWriteStream(aliceTailsFilePath))
})

const request = await faber.requestProofFromAlice()
await alice.sendHolderProof(JSON.parse(request), revRegId => aliceTailsFileDir)
const issuerDid = faber.getFaberDid()
const request = await faber.requestProofFromAlice(proofRequestDataStandard(issuerDid))
await alice.sendHolderProof(JSON.parse(request), revRegId => aliceTailsFileDir, { attribute_3: 'Smith' })
await faber.updateStateVerifierProof(VerifierStateType.Finished)
await alice.updateStateHolderProof(ProverStateType.Finished)
} catch (err) {
Expand Down
138 changes: 122 additions & 16 deletions agents/node/vcxagent-core/test/issue-verify.spec.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,142 @@
/* eslint-env jest */
require('jest')
const { createPairedAliceAndFaber } = require('./utils/utils')
const { IssuerStateType, HolderStateType, ProverStateType, VerifierStateType } = require('@hyperledger/node-vcx-wrapper')
const { IssuerStateType, HolderStateType, ProverStateType, VerifierStateType, ProofState } = require('@hyperledger/node-vcx-wrapper')
const sleep = require('sleep-promise')
const { initRustLogger } = require('../src')
const { proofRequestDataStandard, proofRequestDataSelfAttest } = require('./utils/data')
const path = require('path')

beforeAll(async () => {
jest.setTimeout(1000 * 60 * 4)
initRustLogger(process.env.RUST_LOG || 'vcx=error')
})

afterAll(async () => {
await sleep(500)
})

describe('test update state', () => {
it('Faber should send credential to Alice', async () => {
try {
const { alice, faber } = await createPairedAliceAndFaber()
const tailsDir = `${__dirname}/tmp/faber/tails`
await faber.buildLedgerPrimitives({ tailsDir, maxCreds: 5 })
await faber.rotateRevReg(tailsDir, 5)
await faber.sendCredentialOffer()
await alice.acceptCredentialOffer()
it('Faber should issue credential, verify proof', async () => {
const { alice, faber } = await createPairedAliceAndFaber()
const issuerDid = faber.getFaberDid()
const tailsDir = path.join(__dirname, '/tmp/faber/tails')
await faber.buildLedgerPrimitives({ tailsDir, maxCreds: 5 })
await faber.rotateRevReg(tailsDir, 5)
await faber.sendCredentialOffer()
await alice.acceptCredentialOffer()

await faber.updateStateCredential(IssuerStateType.RequestReceived)
await faber.sendCredential()
await alice.updateStateCredential(HolderStateType.Finished)
await faber.receiveCredentialAck()
await faber.updateStateCredential(IssuerStateType.RequestReceived)
await faber.sendCredential()
await alice.updateStateCredential(HolderStateType.Finished)
await faber.receiveCredentialAck()

const request = await faber.requestProofFromAlice()
await alice.sendHolderProof(JSON.parse(request), revRegId => tailsDir)
const request = await faber.requestProofFromAlice(proofRequestDataStandard(issuerDid))
await alice.sendHolderProof(JSON.parse(request), revRegId => tailsDir, { attribute_3: 'Smith' })
await faber.updateStateVerifierProof(VerifierStateType.Finished)
await alice.updateStateHolderProof(ProverStateType.Finished)
const { presentationVerificationState, presentationAttachment, presentationRequestAttachment } = await faber.getPresentationInfo()
expect(presentationVerificationState).toBe(ProofState.Verified)
expect(presentationRequestAttachment.requested_attributes).toStrictEqual({
attribute_0: {
names: [
'name',
'last_name',
'sex'
],
restrictions: [
{
issuer_did: 'V4SGRU86Z58d6TV7PBUe6f'
}
]
},
attribute_1: {
name: 'date',
restrictions: {
issuer_did: 'V4SGRU86Z58d6TV7PBUe6f'
}
},
attribute_2: {
name: 'degree',
restrictions: {
'attr::degree::value': 'maths'
}
},
attribute_3: {
name: 'nickname',
self_attest_allowed: true
}
})
expect(presentationAttachment.requested_proof).toStrictEqual({
revealed_attrs: {
attribute_1: {
sub_proof_index: 0,
raw: '05-2018',
encoded: '101085817956371643310471822530712840836446570298192279302750234554843339322886'
},
attribute_2: {
sub_proof_index: 0,
raw: 'maths',
encoded: '78137204873448776862705240258723141940757006710839733585634143215803847410018'
}
},
revealed_attr_groups: {
attribute_0: {
sub_proof_index: 0,
values: {
sex: {
raw: 'female',
encoded: '71957174156108022857985543806816820198680233386048843176560473245156249119752'
},
name: {
raw: 'alice',
encoded: '19831138297880367962895005496563562590284654704047651305948751287370224856720'
},
last_name: {
raw: 'clark',
encoded: '51192516729287562420368242940555165528396706187345387515033121164720912081028'
}
}
}
},
self_attested_attrs: {
attribute_3: 'Smith'
},
unrevealed_attrs: {},
predicates: {
predicate_0: {
sub_proof_index: 0
}
}
})
})

it('Faber should verify proof with self attestation', async () => {
try {
const { alice, faber } = await createPairedAliceAndFaber()
const request = await faber.requestProofFromAlice(proofRequestDataSelfAttest())
await alice.sendHolderProofSelfAttested(JSON.parse(request), { attribute_0: 'Smith' })
await faber.updateStateVerifierProof(VerifierStateType.Finished)
await alice.updateStateHolderProof(ProverStateType.Finished)
const { presentationVerificationState, presentationAttachment, presentationRequestAttachment } = await faber.getPresentationInfo()
expect(presentationVerificationState).toBe(ProofState.Verified)
expect(presentationAttachment.requested_proof).toStrictEqual({
revealed_attrs: {},
self_attested_attrs: {
attribute_0: 'Smith'
},
unrevealed_attrs: {},
predicates: {}
})
expect(presentationRequestAttachment.requested_attributes).toStrictEqual({
attribute_0: {
name: 'nickname',
self_attest_allowed: true
}
})
await sleep(500)
} catch (err) {
await sleep(2000)
await sleep(500)
console.error(`err = ${err.message} stack = ${err.stack}`)
throw Error(err)
}
Expand Down
Loading

0 comments on commit 516bdb9

Please sign in to comment.