Skip to content
This repository has been archived by the owner on Dec 12, 2022. It is now read-only.

Code Examples

Derk Norton edited this page Jun 3, 2020 · 46 revisions

Importing the Modules

The following code shows how to import the Bali Digital Notary™ package and how to initialize the notary API.

const debug = 1;  // debug level: [0..3]
const bali = require('bali-component-framework').api(debug);
const account = bali.tag();  // new account
const directory = 'config/';  // for testing purposes only
const notary = require('bali-digital-notary').test(account, directory, debug);

The debug level can be set to one of the following values:

  • 0 - no logging to console.log or console.error will occur
  • 1 - exceptions will be logged to console.error
  • 2 - additional validation of arguments passed into the API will occur
  • 3 - detailed information will be logged to console.log

Note that the above example uses a test version of the digital notary. The actual statements required depends on whether the code resides in a client application or if it is part of a secure service.

Client Application

When implementing a client application that uses a BLE enabled hardware security module (HSM) use the following declarations:

const hsm = require('bali-hsm-proxy').proxy(directory, debug);  // hardware security module proxy
const notary = require('bali-digital-notary').notary(hsm, account, directory, debug);

Service Implementation

When implementing a secure remote service use something like the following declarations:

const notary = require('bali-digital-notary').service(debug);

Generating a Notary Key

The following code examples show how to generate a new notary key and its associated public certificate.

var certificate = await notary.generateKey();
console.log('public certificate: ' + certificate);

This code (and all code in these examples) must be run within an asynchronous function since it makes calls on the notary API which is also an asynchronous API. The notary key is kept private within the digital notary object whereas the public certificate is returned as a document.

The resulting public certificate document is displayed below using Bali Document Notation.

public certificate: [
    $publicKey: '09AJQ7NJSKSKBJMGT3K21KZTZZF2C58B42FP72BSBZQVZ56P9HV0'
    $algorithms: [
        $digest: "SHA512"
        $signature: "ED25519"
    ]
](
    $type: /bali/notary/Certificate/v1
    $tag: #3Q63XLP6N0PHDMDC4YNTTJX4GS203CN7
    $version: v1
    $permissions: /bali/permissions/public/v1
    $previous: none
)

All documents including this certificate are parameterized by standard attributes that are required during the notarization process. These include the $type of the document, the unique $tag and $version string that identify the document, a named reference to the $permissions that define who is allowed to access the document, and finally, a document citation to the $previous version of the document if one exists (in this case it doesn't since this is the first version of the notary key).

Notarizing the Public Certificate

The next code examples show how to notarize the public certificate using the new notary key to create a notarized contract.

certificate = await notary.notarizeDocument(certificate);
console.log('notarized certificate: ' + certificate);

The resulting notarized public certificate is displayed below.

notarized certificate: [
    $protocol: v2
    $timestamp: <2020-06-03T20:39:54.839>
    $account: #XR3JC5SNH03M6R1K0XMKY3CDXF40CY5Z
    $document: [
        $publicKey: '09AJQ7NJSKSKBJMGT3K21KZTZZF2C58B42FP72BSBZQVZ56P9HV0'
        $algorithms: [
            $digest: "SHA512"
            $signature: "ED25519"
        ]
    ](
        $type: /bali/notary/Certificate/v1
        $tag: #3Q63XLP6N0PHDMDC4YNTTJX4GS203CN7
        $version: v1
        $permissions: /bali/permissions/public/v1
        $previous: none
    )
    $certificate: none
    $signature: '
        QRNDQ8VL46FCKGMYV2GLQMBHQD0RFMMN1XTV9LB3V17RX7TGAPVNKJ6H2D6T
        D28MT0DMRJHBJ7YK345L2G0KYT6L8YRJKMGJX76F41R
    '
]($type: /bali/notary/Contract/v1)

Notice that the document containing the public certificate has been embedded within a contract that contains additional information about the $account that owns the certificate, and a digital $signature that can be used to verify the authenticity of the certificate using the embedded $publicKey.

Activating the Private Notary Key

A private notary key must be activated using its associated notarized public certificate before it can be used to notarize additional documents. The next example shows how to do this.

var citation = await notary.activateKey(certificate);
console.log('certificate citation: ' + citation);

A document citation referencing the public certificate is returned. It is displayed below.

certificate citation: [
    $protocol: v2
    $tag: #3Q63XLP6N0PHDMDC4YNTTJX4GS203CN7
    $version: v1
    $digest: '
        88WYW89LHWXMZ2P5B99JJKGXQ8RZTH59TFRRZCYYS7HBVNTX1X1DBY7L147Q
        Q7A526SGWDY614WQ5KPPMMVPW5QZ70BL0NXLN96ZS9H
    '
]($type: /bali/notary/Citation/v1)

Each document citation contains attributes describing the version of the security $protocol used to create the citation, the unique $tag and $version string for the cited document, and a digital $digest (or fingerprint) of the cited document that can be used to verify that the document has not been modified or corrupted since it was created. If even a single character in the cited document is changed, the digital digest in the document citation will be completely different.

Notarizing a Document

The next code example shows how to create and notarize an example transaction document. First, we create a new document specifying its type and using a JavaScript object to define the attributes that are included in the transaction.

const transaction = bali.instance('/starbucks/types/Transaction/v2.3', {
    $timestamp: bali.moment(),  // now
    $consumer: 'Derk Norton',
    $merchant: '<https://www.starbucks.com/>',
    $amount: '4.95($currency: $USD)'
});
console.log('transaction: ' + transaction);

The result is the transaction document.

$transaction: [
    $timestamp: <2020-06-03T20:39:54.906>
    $consumer: "Derk Norton"
    $merchant: <https://www.starbucks.com/>
    $amount: 4.95($currency: $USD)
](
    $type: /starbucks/types/Transaction/v2.3
    $tag: #DF7V9NX82DNYFZ1FCGRSWSFDDKW6Y7R9
    $version: v1
    $permissions: /bali/permissions/Public/v1
    $previous: none
)

Again, the transaction document is parameterized by the standard attributes that are required by all documents that are to be notarized.

Once we have defined a document containing the transaction information, we can notarize it as follows.

const contract = await notary.notarizeDocument(transaction);
console.log('contract: ' + contract);

The result is a notarized contract containing the transaction document.

contract: [
    $protocol: v2
    $timestamp: <2020-06-03T20:39:54.912>
    $account: #XR3JC5SNH03M6R1K0XMKY3CDXF40CY5Z
    $document: [
        $timestamp: <2020-06-03T20:39:54.906>
        $consumer: "Derk Norton"
        $merchant: <https://www.starbucks.com/>
        $amount: 4.95($currency: $USD)
    ](
        $type: /starbucks/types/Transaction/v2.3
        $tag: #DF7V9NX82DNYFZ1FCGRSWSFDDKW6Y7R9
        $version: v1
        $permissions: /bali/permissions/Public/v1
        $previous: none
    )
    $certificate: [
        $protocol: v2
        $tag: #3Q63XLP6N0PHDMDC4YNTTJX4GS203CN7
        $version: v1
        $digest: '
            88WYW89LHWXMZ2P5B99JJKGXQ8RZTH59TFRRZCYYS7HBVNTX1X1DBY7L147Q
            Q7A526SGWDY614WQ5KPPMMVPW5QZ70BL0NXLN96ZS9H
        '
    ]($type: /bali/notary/Citation/v1)
    $signature: '
        24GXP6Y6P1H0Y3P4LN2SXH0F9NR0JAVR4MQH9247X2FMXMJN2TH83XRZ0795
        S0T2S3AWVLFCV7M3R7K8CTXC580R77KD5ANR7GKDR2H
    '
]($type: /bali/notary/Contract/v1)

Notice that the structure of this contract is the same as the notarized public certificate. However, in this contract, the $certificate attribute contains a document citation to the public certificate that can be used to validate the digital $signature on this document. In fact, it cites the public certificate for our private notary key since it was our notary key that was used to notarize this transaction. Look closely and you will see that it matches the certificate citation displayed earlier.

In the notarized public certificate, the $certificate attribute was set to none since it is not possible to create a document citation to a document before that document exists and in the case of the notarized public certificate, that document would be attempting to cite itself.

Validating a Notarized Contract

Now let's look at how one goes about validating a notarized contract.

const isValid = await notary.validDocument(contract, certificate);
console.log('is valid: ' + isValid);

It's very easy, we just pass to the notary the notarized contract for the transaction, along with the notarized public certificate cited within the transaction document. The digital notary knows how to use the public key within the public certificate to validate the digital signature within the transaction contract. Because the public certificate is the same one that was generated and notarized by our digital notary, the signature should be valid.

is valid: true

And it is.

Citing a Notarized Document

Just as we have a document citation to our notarized public certificate, we can create a document citation to our newly notarized transaction document.

citation = await notary.citeDocument(transaction);
console.log('transaction citation: ' + citation);

Note that we pass in the transaction document, not the notarized contract.

The resulting document citation for the transaction is displayed below.

transaction citation: [
    $protocol: v2
    $tag: #DF7V9NX82DNYFZ1FCGRSWSFDDKW6Y7R9
    $version: v1
    $digest: '
        MLQSXVJKJRKZ3VK80WMLQA78YD7XR8P74SQNHGR0JJC2XTBD1YFMWQABL8M3
        MZ420WPTXCNS06CKLZFX2WA1ZZYT1M72536NS0PYADR
    '
]($type: /bali/notary/Citation/v1)

It has the same attributes as any other document citation. The values of the identifying attributes and the digital digest are different from the values for the certificate citation of course since this one is citing a different document.

Validating a Document Citation

Similar to using a notarized public certificate to validate the digital signature in a notarized contract, we can use the digital digest in a document citation to verify that the cited document has not been modified or corrupted in any way.

const citationMatches = await notary.citationMatches(citation, transaction);
console.log('citation matches: ' + citationMatches);

In this case, the document citation and cited document are passed to the digital notary to confirm that the citation matches.

citation matches: true

Which of course it does.