Python support

The nShield Python module nfddds can be used to encode and decode between the DDDS wire format and a Python representation of the DDDS objects.

nfddds.encode accepts any Python object which can be interpreted as a DDDS object:

Python class DDDS equivalent

int

integer

str

string

nfddds.Symbol

symbol

bytes

bytearray

nfkm.ByteBlock

byte-block

bool

symbols 'True' and 'False'

tuple

list

list

dict

map

set

set

nfddds.decode accepts input which can be interpreted as a list of octets, i.e. a byte string, byte array, list of integers or nfkm.ByteBlock.

Below are a few examples using the nfddds module. A longer use case can be seen in the nShield Warrants appnote where nfddds is used to decode and view an HSM warrant.

Example 1 - decoding a string and symbol

As per the wire format specification, the first octet 0x25 indicates a DDDS string where the following 5 octets are the UTF-8 encoding of the string. If the first octet is replaced by 0x35, this will be a DDDS symbol made up of 5 octets.

>>> nfddds.decode([0x25, 0x68, 0x65, 0x6c, 0x6c, 0x6f])
'hello'
>>> type(nfddds.decode([0x25, 0x68, 0x65, 0x6c, 0x6c, 0x6f]))
<class 'nfddds.String'>

>>> nfddds.decode([0x35, 0x68, 0x65, 0x6c, 0x6c, 0x6f])
'hello'
>>> type(nfddds.decode([0x35, 0x68, 0x65, 0x6c, 0x6c, 0x6f]))
<class 'nfddds.Symbol'>

Example 2 - decoding a map

The first octet 0xb3 indicates a DDDS map with three key-value pairs. In this example, the keys are one-octet DDDS integers and the values are two-octect DDDS strings.

>>> nfddds.decode([0xb3, 0x00, 0x21, 0x61, 0x01, 0x21, 0x62, 0x02, 0x21, 0x63])
{0: 'a', 1: 'b', 2: 'c'}

Example 3 - encoding a set and list

If a Python set and list contain the same elements and list(setname) == listname, they will encode to the same wire format, except the first four bits will be 1001 (or hex 9) for lists and 1010 (or hex a) for sets.

>>> nfddds.encode({1, 2, 3, 4})
b'\xa4\x01\x02\x03\x04'

>>> nfddds.encode([1, 2, 3, 4])
b'\x94\x01\x02\x03\x04'