UNPKG

doauthor

Version:

A client for DoAuth: a fast, lean and reliable authentication server based on verifiable credentials standard

284 lines (279 loc) 11.7 kB
<!doctype html> <html> <head> <title>doauthor demo</title> </head> <body> <label>Test ID:</label> <pre id="test-id"></pre> <label>Doauthor loading:</label> <div id="doauthor-status" class="test">pending</div> <label>Doauthor performing:</label> <div id="performance-is-ok" class="test">pending</div> <label>URLSafe Base64 is tripping:</label> <div id="base64-suite" class="test">pending</div> <label>KDF works and makes valid signing keys:</label> <div id="kdf" class="test">pending</div> <ul> <li> <label>The slip:</label> <pre id="slip"></pre> </li> <li> <label>Signing key used:</label> <pre id="kdf-info"></pre> </li> </ul> <label>MainKeyInit2 generates a distinct key:</label> <div id="distinct" class="test">pending</div> <label>Main key gets reproduced from stored slip:</label> <div id="localstorage" class="test">pending</div> <label>"Verify map" of "sign map" is "true":</label> <div id="verify_map__sign_map" class="test">pending</div> <label>Credential compliance with the reference implementation:</label> <div id="credential-compatibility" class="test">pending</div> <!-- iex(19)> %{public: "dW8Z2z2icecILIyAdrjaOqkurfC99ocFR87r9QX_mJQ=", secret: "H9xUHnIAxdYuslQ8UULO8A0eXf6gH2ySEfo2-kdZZow32Nza1n_O_YdP4Qg7JuCbt8ieMOZkFypb-UbAWVLKCg=="} |> Witchcraft.Functor.map(fn x -> Uptight.Base.mk_url!(x).raw |> Uptight.Binary.new!() end) |> DoAuth.Credential.mk_credential!(%{"hello" => "world"}, issuanceDate: ~N[2021-08-17 22:49:56] |> DateTime.from_naive!("Etc/UTC")) |> Jason.encode!(pretty: true) |> IO.puts() { "@context": [], "credentialSubject": { "hello": "world" }, "id": "5rQ5V1M3QzCCFOH_w1xu0ondNWLyn8sd4-p3-AiS3GXKLjO4J4BUWLM1xH-CfFcd-LPj-ys908SjHMa-WOq-AA==", "issuanceDate": "2021-08-17T22:49:56Z", "issuer": "dW8Z2z2icecILIyAdrjaOqkurfC99ocFR87r9QX_mJQ=", "proof": { "created": "2021-12-07T13:57:55.931383Z", "proofPurpose": "assertionMethod", "signature": "5rQ5V1M3QzCCFOH_w1xu0ondNWLyn8sd4-p3-AiS3GXKLjO4J4BUWLM1xH-CfFcd-LPj-ys908SjHMa-WOq-AA==", "type": "Libsodium2021", "verificationMethod": "dW8Z2z2icecILIyAdrjaOqkurfC99ocFR87r9QX_mJQ=" }, "type": [] } :ok --> <pre id="credential-target"> { "@context": [], "credentialSubject": { "hello": "world" }, "id": "5rQ5V1M3QzCCFOH_w1xu0ondNWLyn8sd4-p3-AiS3GXKLjO4J4BUWLM1xH-CfFcd-LPj-ys908SjHMa-WOq-AA==", "issuanceDate": "2021-08-17T22:49:56Z", "issuer": "dW8Z2z2icecILIyAdrjaOqkurfC99ocFR87r9QX_mJQ=", "proof": { "created": "2021-12-07T13:57:55.931383Z", "proofPurpose": "assertionMethod", "signature": "5rQ5V1M3QzCCFOH_w1xu0ondNWLyn8sd4-p3-AiS3GXKLjO4J4BUWLM1xH-CfFcd-LPj-ys908SjHMa-WOq-AA==", "type": "Libsodium2021", "verificationMethod": "dW8Z2z2icecILIyAdrjaOqkurfC99ocFR87r9QX_mJQ=" }, "type": [] } </pre> <label>Presentations compliance with the reference implementation:</label> <div id="presentation-compatibility" class="test">pending</div> <!-- iex(18)> DoAuth.Credential.present_credential_map(kp, cred_map, issuanceDate: tau1) |> Uptight.Result.from_ok() |> Jason.encode!(pretty: true) |> IO.puts { "issuanceDate": "2021-12-19T02:31:30Z", "issuer": "dW8Z2z2icecILIyAdrjaOqkurfC99ocFR87r9QX_mJQ=", "proof": { "signature": "RYa98wyKQ8Gl2GrtYVxUFXPs7m9PFL9wT09xv368dJzK9aJIJ8gZreiugOuKCLtljFex2QWH58Az79x99PyGAg==", "timestamp": "2021-12-19 04:05:50.471122Z", "verificationMethod": "dW8Z2z2icecILIyAdrjaOqkurfC99ocFR87r9QX_mJQ=" }, "verifiableCredential": { "@context": [], "credentialSubject": { "hello": "world" }, "id": "5rQ5V1M3QzCCFOH_w1xu0ondNWLyn8sd4-p3-AiS3GXKLjO4J4BUWLM1xH-CfFcd-LPj-ys908SjHMa-WOq-AA==", "issuanceDate": "2021-08-17T22:49:56Z", "issuer": "dW8Z2z2icecILIyAdrjaOqkurfC99ocFR87r9QX_mJQ=", "proof": { "created": "2021-12-07T13:57:55.931383Z", "proofPurpose": "assertionMethod", "signature": "5rQ5V1M3QzCCFOH_w1xu0ondNWLyn8sd4-p3-AiS3GXKLjO4J4BUWLM1xH-CfFcd-LPj-ys908SjHMa-WOq-AA==", "type": "Libsodium2021", "verificationMethod": "dW8Z2z2icecILIyAdrjaOqkurfC99ocFR87r9QX_mJQ=" }, "type": [] } } --> <pre id="presentation-target"> { "issuanceDate": "2021-12-19T02:31:30Z", "issuer": "dW8Z2z2icecILIyAdrjaOqkurfC99ocFR87r9QX_mJQ=", "proof": { "signature": "RYa98wyKQ8Gl2GrtYVxUFXPs7m9PFL9wT09xv368dJzK9aJIJ8gZreiugOuKCLtljFex2QWH58Az79x99PyGAg==", "timestamp": "2021-12-19 04:05:50.471122Z", "verificationMethod": "dW8Z2z2icecILIyAdrjaOqkurfC99ocFR87r9QX_mJQ=" }, "verifiableCredential": { "@context": [], "credentialSubject": { "hello": "world" }, "id": "5rQ5V1M3QzCCFOH_w1xu0ondNWLyn8sd4-p3-AiS3GXKLjO4J4BUWLM1xH-CfFcd-LPj-ys908SjHMa-WOq-AA==", "issuanceDate": "2021-08-17T22:49:56Z", "issuer": "dW8Z2z2icecILIyAdrjaOqkurfC99ocFR87r9QX_mJQ=", "proof": { "created": "2021-12-07T13:57:55.931383Z", "proofPurpose": "assertionMethod", "signature": "5rQ5V1M3QzCCFOH_w1xu0ondNWLyn8sd4-p3-AiS3GXKLjO4J4BUWLM1xH-CfFcd-LPj-ys908SjHMa-WOq-AA==", "type": "Libsodium2021", "verificationMethod": "dW8Z2z2icecILIyAdrjaOqkurfC99ocFR87r9QX_mJQ=" }, "type": [] } } </pre> <label>Credentials are verifiable:</label> <div id="verifiable-credentials" class="test">pending</div> <label>Presentations are verifiable:</label> <div id="verifiable-presentations" class="test">pending</div> </body> <script src="/dist/doauthor.js"></script> <script async defer src="/src/sodium.js"></script> <script> const i = (x) => document.getElementById(x); const ok = (x) => { i(x).innerText = "ok" }; const nok = (x) => { i(x).innerText = "fail" }; const testLoaded = () => { if (__doauthorHasLoaded__ === true) { ok("doauthor-status"); } else { nok("doauthor-status"); } }; const testBase64 = () => { const x = doauthor.crypto.show("show / read are tripping"); if (x === doauthor.crypto.show(doauthor.crypto.read(x))) { ok("base64-suite"); } else { nok("base64-suite"); } }; const password = "this is a password"; const testMainKeyDerivation = () => { const show = doauthor.crypto.show; const mkey = doauthor.crypto.mainKey(password); const skp = doauthor.crypto.deriveSigningKeypair(mkey, 4); const msg = "this is an authenticated message"; const detachedSig = doauthor.crypto.sign(msg, skp); if (true === doauthor.crypto.verify( msg, detachedSig )) { ok("kdf"); i("slip").innerText = doauthor.util.prettyPrint(JSON.parse(localStorage.getItem("slip"))); i("kdf-info").innerText = doauthor.util.prettyPrint({ "public": show(detachedSig.public), "signature": show(detachedSig.signature) }); } else { nok("kdf"); } return mkey; } const testCryptoVerifyMapOfSignMapIsTrue = async (skp) => { const verifiable_map = doauthor.crypto.sign_map(skp, { "hello": { "dangerous": { "world": ["of", "JavaScript"] } } }); const res = await doauthor.crypto.verify_map(verifiable_map); if (true === res) { ok("verify_map__sign_map"); } else { nok("verify_map__sign_map"); } } const testMainKeyInit2GeneratesDistinctKey = (mkey0) => { const show = doauthor.crypto.show; const mkey = doauthor.crypto.mainKey(password); const [mkey1, _slip] = doauthor.crypto.mainKeyInit2(password, doauthor.crypto.slipConfig()); if (show(mkey) !== show(mkey1)) { ok("distinct"); } else { nok("distinct"); } if (show(mkey0) === show(mkey)) { ok("localstorage"); } else { nok("localstorage"); } return doauthor.crypto.deriveSigningKeypair(mkey, 20); } const testCredentialCompatibility = () => { const kp = { "public": doauthor.crypto.read("dW8Z2z2icecILIyAdrjaOqkurfC99ocFR87r9QX_mJQ="), "secret": doauthor.crypto.read("H9xUHnIAxdYuslQ8UULO8A0eXf6gH2ySEfo2-kdZZow32Nza1n_O_YdP4Qg7JuCbt8ieMOZkFypb-UbAWVLKCg==") }; const cred_ours = doauthor.credential.from_claim(kp, { "hello": "world" }, { "issuanceDate": "2021-08-17T22:49:56Z" }); const cred_ref = JSON.parse(i("credential-target").innerText); const our_sig = cred_ours["proof"]["signature"]; const ref_sig = cred_ref["proof"]["signature"]; if (our_sig === ref_sig) { ok("credential-compatibility"); } else { nok("credential-compatibility"); } doauthor.did.memorisePublicKey(kp["public"]); if (doauthor.crypto.verify_map(cred_ours)) { ok("verifiable-credentials"); } else { nok("verifiable-credentials"); } return cred_ours; } const testPresentationCompatibility = () => { const kp = { "public": doauthor.crypto.read("dW8Z2z2icecILIyAdrjaOqkurfC99ocFR87r9QX_mJQ="), "secret": doauthor.crypto.read("H9xUHnIAxdYuslQ8UULO8A0eXf6gH2ySEfo2-kdZZow32Nza1n_O_YdP4Qg7JuCbt8ieMOZkFypb-UbAWVLKCg==") }; cred = JSON.parse(i("credential-target").innerText); const pres_ours = doauthor.credential.present_credential(kp, cred, { "issuanceDate": "2021-12-19T02:31:30Z" }); console.log(pres_ours, JSON.stringify(pres_ours, null, 2)); const pres_ref = JSON.parse(i("presentation-target").innerText); const our_sig = pres_ours["proof"]["signature"]; const ref_sig = pres_ref["proof"]["signature"]; if (our_sig === ref_sig) { ok("presentation-compatibility"); } else { nok("presentation-compatibility"); } doauthor.did.memorisePublicKey(kp["public"]); if (doauthor.crypto.verify_map(pres_ours)) { ok("verifiable-presentations"); } else { nok("verifiable-presentations"); } } const testPerformanceIsOk = (t000, t290, t300) => { if (t300 - t000 < 300 && t300 - t290 < 10) { ok('performance-is-ok'); } else { nok('performance-is-ok'); } } (async () => { t000 = performance.now(); _ok1 = await DoAuthor.require(); t290 = performance.now(); _ok2 = await DoAuthor.require(); t300 = performance.now(); _ok3 = await DoAuthor.require(); i("test-id").innerText = doauthor.crypto.show(sodium.randombytes_buf(8)); testLoaded(); testPerformanceIsOk(t000, t290, t300); testBase64(); const mkey = testMainKeyDerivation(); const skp = testMainKeyInit2GeneratesDistinctKey(mkey); await testCryptoVerifyMapOfSignMapIsTrue(skp); const cred = testCredentialCompatibility(); testPresentationCompatibility(cred); })(); </script> </html>