Documentation

The Blockchain for Things.

A collection of concepts, documentation and tutorials to make your IoT device data trustworthy.

ubirch on GitHub


ubirch - Documentation

Device SDK

Cloud Services

Examples and Tutorials

REST API Documentation

Examples and Tutorials

Before you start

Head over to the ubirch backend portal and register yourself to get access to the backend services. While you could start sending data directly between two devices and do the verification by hand, using the ubirch backend brings you an intermediate step that verifies the signatures, handles the identities (public keys), and provides streaming and blockchain services for verified data.

You will need to register to receive an authorization token for using the API

C/C++

The C/C++ implementation is a generic implementation and only depends on the availability of the required crypto functions ubirch-mbed-nacl-cm0 (for documentation, see Ed25519) and the ubirch-mbed-msgpack library (for documentation, see msgpack-c).

The ubirch-protocol follows the coding paradigm of the msgpack-c implementation:

  1. create a buffer to write to (msgpack_sbuffer_new())
  2. initialize the protocol and the msgpack packer (proto, pk)
  3. write the protocol header (ubirch_protocol_start())
  4. write payload (msgpack_pack_*())
  5. finish the protocol (ubirch_protocol_finish())
  6. send the data from the buffer
  7. clean up (msgpack_sbuffer_clear(), ubirch_protocol_free())

A full, runnable example for the ESP32 platform is located here.

A simple example to send a single signed message:

msgpack_sbuffer *sbuf = msgpack_sbuffer_new();
ubirch_protocol *proto = ubirch_protocol_new(proto_signed, TYPE, sbuf, msgpack_sbuffer_write, ed25519_sign, UUID); //TYPE = 0
msgpack_packer *pk = msgpack_packer_new(proto, ubirch_protocol_write);
ubirch_protocol_start(proto, pk);
// ADD YOUR PAYLOAD DATA HERE
msgpack_pack_int(pk, 99); // exemplary data
// 
ubirch_protocol_finish(proto, pk);
// SEND THE MESSAGE (sbuf->data, sbuf->size)
msgpack_packer_free(pk);
ubirch_protocol_free(proto); 

The corresponding chained message, where we connect subsequent messages using their signature is shown below:

msgpack_sbuffer *sbuf = msgpack_sbuffer_new();
ubirch_protocol *proto = ubirch_protocol_new(proto_chained, TYPE, sbuf, msgpack_sbuffer_write, ed25519_sign, UUID); //TYPE =  0
msgpack_packer *pk = msgpack_packer_new(proto, ubirch_protocol_write);

// FIRST MESSAGE
ubirch_protocol_start(proto, pk);
msgpack_pack_raw(pk, strlen(TEST_PAYLOAD));
msgpack_pack_raw_body(pk, TEST_PAYLOAD, strlen(TEST_PAYLOAD));
ubirch_protocol_finish(proto, pk);
// STORE THE CURRENT SIGNATURE (proto->signature, UBIRCH_PROTOCOL_SIGN_SIZE)
// SEND THE MESSAGE (sbuf->data, sbuf->size)
msgpack_sbuffer_clear(sbuf);

// SUBSEQUENT MESSAGE
memcpy(proto->signature, LAST_SIGNATURE, UBIRCH_PROTOCOL_SIGN_SIZE); // LOAD THE SIGNATURE INTO *proto
ubirch_protocol_start(proto, pk);
msgpack_pack_raw(pk, strlen("CHAINED"));
msgpack_pack_raw_body(pk, "CHAINED", strlen("CHAINED"));
ubirch_protocol_finish(proto, pk);
// STORE THE CURRENT SIGNATURE (proto->signature, UBIRCH_PROTOCOL_SIGN_SIZE)
// SEND THE MESSAGE (sbuf->data, sbuf->size)

msgpack_packer_free(pk);
ubirch_protocol_free(proto); 

The response verification is described in the example-esp32: message response verification

Python Client

Python client is a Python3 implementation of ubirch protocol.

The library consists of three parts which can be used individually:

A full, runnable example is located here.

Setting up api, keystore and protocol

import ubirch 

# minimal ubirch protocol impl that allows you to send signed messages
class Proto(ubirch.Protocol):
    def __init__(self, keystore):
        super().__init__()
        self.__ks = keystore
    def _sign(self, uuid, message):
        return self.__ks.find_signing_key(uuid).sign(message)
        

keystore = ubirch.KeyStore("example-keystore.jks", "example-password")
api = ubirch.API("<YOUR_AUTH_TOKEN>", "dev")

protocol = Proto(keystore)

Initializing the KeyStore and registering keys

keystore.create_ed25519_keypair(identity_uuid)
reg_message = protocol.message_signed(identity_uuid, UBIRCH_PROTOCOL_TYPE_REG,
                                      keystore.get_certificate(identity_uuid))
registration_resp = api.register_identity(reg_message)

Creating a device

device_create_resp = api.device_create({
    "deviceId": str(device_uuid),
    # device types available at Avatar service's endpoint /device/deviceType
    "deviceTypeKey": device_type,  
    "deviceName": device_name,
    # you can put group uuids here, so other users see the device
    "groups": ["db1488ae-becc-40a3-a5c2-b6daadd6715b"],
    "hwDeviceId": str(device_hwid),
    "tags": ["python-example", "python-client"],
    "deviceProperties": {
        "storesData": True,
        "blockChain": False
    },
    "created": "{}Z".format(datetime.utcnow()
                        .strftime('%Y-%m-%dT%H:%M:%S.%f')[:-3])
})

Sending messages

In general, sending messages looks like this:

message = protocol.message_*(<uuid>, <message_type>, <payload>)
response = api.send(message)

Here are some examples with concrete payload types:

Sealing and verifying integrity of messages

This is useful when you want to verify the integrity of messages, but don’t want to share the messages themself with ubirch.

payload = b"<YOUR_SENSITIVE_PAYLOAD>"
payload_hash = hashlib.sha512(payload).digest()  # use hashing function of your choice
message = protocol.message_chained(device_uuid, UBIRCH_PROTOCOL_TYPE_BIN, payload_hash)
seal_response = api.send(message)

send_to_your_own_backend(payload)

And then in your backend, to verify the validity of the received message

payload = receive_sensitive_message()
payload_hash = hashlib.sha512(payload).digest()
hash_b64 = bytes.decode(base64.b64encode(payload_hash))

from urllib.parse import quote
import requests

response = requests.get(
    "https://api.ubirch.{}.ubirch.com/api/avatarService/v1/device/verify/{}"
    .format("<YOUR_UBIRCH_ENV>", quote(received_message_hash, safe="+=")), 
    headers=api._auth
)
    
is_message_valid = response.ok

JavaScript

work in progress