Programmable Envelopes

Programmable envelopes contain predefined fields to allow different types of messages to be sent according to specific use case requirements. Mailchain is flexible and extensible, adding a messaging layer to blockchain protocols, supporting different types of messages to be sent. Blockchain protocols typically allow sending data as a byte array, which is efficient but not descriptive. Programmable Envelopes allow descriptive implementations of messaging use cases that can be encoded to a byte array.

Each envelope is implemented as code, describing the encoding method, fields, and interface functions.

Programmable Envelopes are preferred over adding optional fields. They remove some of the complexity, the need for additional documentation, are extensible in a modular sense, and create an improved developer experience.

Backwards and forwards compatibility can be achieved by never modifying an envelope after deployment.

Data Interface

Each envelope is required to implement a data interface. It will have different combinations of data fields to return a valid response for each of these methods. This interface is defined as:

type Data interface {
URL(decrypter cipher.Decrypter) (url *url.URL, err error)
IntegrityHash(decrypter cipher.Decrypter) (hash []byte, err error)
ContentsHash(decrypter cipher.Decrypter) (hash []byte, err error)
Valid() error
}

URL

Addressable location of the message, the URL may be encrypted requiring decrypter to be supplied to decrypt URL.

Parameters:

Name

Type

Notes

decrypter

cipher.decrypter

Used to decrypt the URL where the message can be found. Decrypter is required but is only used if the url is stored encrypted.

Returns:

Name

Type

Notes

url

*url.URL

Address of the message. Nil if error.

err

error

Error object describing the cause.

IntegrityHash

Hash of the encrypted content. This can be used to validate the integrity of the envelope contents before decrypting.

Parameters:

Name

Type

Notes

decrypter

cipher.decrypter

Used to decrypt the hash, where only the intended recipient can validate the contents. Decrypter is required but is only used if the hash is stored encrypted.

Returns:

Name

Type

Notes

hash

[]byte

Hash of the contents to validate integrity. Nil if error.

err

error

Error object describing the cause.

Integrity Hash is not intended to be cryptographically secure, use ContentsHash for a secure cryptographic hash.

ContentsHash

Hash of the decrypted content. This can be used to verify the contents of the message have not been tampered with.

Parameters:

Name

Type

Notes

decrypter

cipher.decrypter

Used to decrypt the hash, where only the intended recipient can verify the contents. Decrypter is required but is only used if the hash is stored encrypted.

Returns:

Name

Type

Notes

hash

[]byte

Hash of the contents to validate the message contents. Nil if error.

err

error

Error object describing the cause.

Encoding

The first byte will describe the envelope implementation and encoding method used.

Byte Value

Notes

0x00

Reserved for unset value

0x01

Private message stored with MLI

0x50

Alpha envelope

0xFF

Reserved to extend beyond 255 envelope definitions

While Protocol buffers are used by the first implemented envelopes, this is not a requirement. Each envelope describes it encoding method in the definition.

Envelopes

0x00 - Reserved for unset value

Zero value is reserved to identify that it has not been set and should be treated like an unset envelope identifier.

0x01 - Private Message Stored with MLI

Is optimized for secure, verifiable messaging with minimal bytes, URL and ContentsHash are encrypted with a publicly verified IntegrityHash. 0x01 uses MLI to reduce the bytes needed to store the URL, the IntegrityHash is optional reducing the required number of bytes.

Encoding

Protocol buffers are used to define the structure of this message. This is the proto3 spec.

// Use hosted location where the decryptedhash is the same as the location. Location, decrypted hash are encrypted so only receipient can location and verify the message.
message ZeroX01 {
bytes UIBEncryptedLocationHash = 1;
bytes encryptedHash = 2;
}

Fields

Name

Type

Notes

UIBEncryptedLocationHash

bytes

Required - Bytes are stored are represented with UInt64Bytes.

encryptedHash

bytes

Optional - Bytes of hash

0x50 - Alpha