Keysight/python-trsfile

numpy transformer example

Closed this issue · 8 comments

Hi there!

Is there some demo for npy or npz format to trs file?

Hi liliaoyuan,

There was no such demo, but I made a simple example for you:

from trsfile import Trace
from trsfile.common import Header, TracePadding, SampleCoding

import trsfile
import numpy as np

np.savez('123.npz', a=np.array([1, 2, 3]), b=np.array([4, 5, 6]))

data = np.load('123.npz')

with trsfile.trs_open(
        'trace-set.trs',
        'w',
        engine='TrsEngine',
        headers={
            Header.TRS_VERSION: 2,
            Header.SCALE_X: 1,  # Scaling factor on input data
            Header.SCALE_Y: 1,  # Scaling factor on input data
            Header.DESCRIPTION: 'Sample trace set creation'
        }
) as traces:
    for entry in data.items():
        traces.append(
            Trace(
                SampleCoding.FLOAT,
                entry[1],
                None)
        )

This assumes the most basic structure for an NPZ file, so you'd have to adapt it to your problem. Hope that helps; otherwise, feel free to ask here.

Thanks a lot

Actually my data is like two dimension matrix [voltage-][plaintext], they are numpy array.

AS the trace is like to voltage data and sampling point, How should I address my plaintext. Would that be somewhere the trs slice is ?

BTW, the key is also a factory influnce the outcome, so where it would be defined?

Hi liliaoyuan,

Trace sets have the option to add global data, which applies to the entire trace set, as well as per-trace data, which can be different for each trace. Global data can be added to the header in a TraceSetParameterMap, and per-trace data can be added through a TraceParameterMap. I've added both to the previous example to demonstrate:

from trsfile import Trace
from trsfile.common import Header, SampleCoding

import trsfile
import numpy as np

from trsfile.parametermap import TraceSetParameterMap, TraceParameterMap
from trsfile.standardparameters import StandardTraceSetParameters, StandardTraceParameters

np.savez('123.npz', a=np.array([1, 2, 3]), b=np.array([4, 5, 6]))

data = np.load('123.npz')

parameters = TraceSetParameterMap()
# Set of standard trace set parameters has been defined; e.g. KEY
parameters.add_standard_parameter(StandardTraceSetParameters.KEY, bytes.fromhex('CAFEBABEDEADBEEF0001020304050607'))
# However, any custom parameter is allowed
parameters.add_parameter("Additional data", "Example value")

with trsfile.trs_open(
        'trace-set.trs',
        'w',
        engine='TrsEngine',
        headers={
            Header.TRS_VERSION: 2,
            Header.SCALE_X: 1,  # Scaling factor on input data
            Header.SCALE_Y: 1,  # Scaling factor on input data
            Header.DESCRIPTION: 'Sample trace set creation',
            Header.TRACE_SET_PARAMETERS: parameters
        }
) as traces:
    for entry in data.items():
        traceparameters = TraceParameterMap()
        # Set of standard trace parameters has been defined; e.g. INPUT (plaintext)
        traceparameters.add_standard_parameter(StandardTraceParameters.INPUT, bytes.fromhex('0123456789abcdef0123456789abcdef'))
        # However, any custom parameter is allowed
        traceparameters.add_parameter("Additional trace parameter", "Example value")
        traces.append(
            Trace(
                SampleCoding.FLOAT,
                entry[1],
                traceparameters)
        )

Some additional notes:

  • You don't need to use standard parameters, but they've been defined as such because that's how Inspector, our Java SCA suite, would expect to find them
  • Make sure that each TraceParameterMap is the same size. This is a requirement of the TRS format (because a constant size of traces makes finding an arbitrary trace much quicker)
  • Your key might not be the same for each trace (depending on your data set). If that's the case, it should be added to the TraceParameterMap instead (i.e. different for each trace)

Hope that helps!

It works using add_standard_paramete and add_parameter("Additional data", "Example value")

However since there is no spec statement in the document, I am still confused about the useage of these two

in my case:
image
image

what should the plaintext be in the parametermap set. here My data is all DEC

Lastly, since the creating the trs is no more than address the data by DPA

any more straightforward way like below:
trace = trs.()
plaintext = tra.()
OutpuT = DPAattack(AesSbox(),Increamentcpa())
params.analysisi.leakage = [HW()]

Hi @liliaoyuan ,

I don't think I understand the last part of your question. However, I have tried to provide you with an example closer to what you're working with. I've created some dummy values for plaintext. Since you mentioned they're decimal, I assumed you meant that they are decimal representations of hex byte values, so I've kept them in the range [0,255]. Additionally, I've changed the example to use NPY files, since that seems to be what you're using.

import random

from trsfile import Trace
from trsfile.common import Header, SampleCoding

import trsfile
import numpy as np

from trsfile.parametermap import TraceSetParameterMap, TraceParameterMap
from trsfile.standardparameters import StandardTraceSetParameters, StandardTraceParameters

np.save('power.npy', np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]))
np.save('plaintext.npy', np.array([random.sample(range(0, 255), 16),
                                   random.sample(range(0, 255), 16),
                                   [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]]))

power = np.load('power.npy')
plaintext = np.load('plaintext.npy')

parameters = TraceSetParameterMap()
# Set of standard trace set parameters has been defined; e.g. KEY
parameters.add_standard_parameter(StandardTraceSetParameters.KEY, bytes.fromhex('CAFEBABEDEADBEEF0001020304050607'))
# However, any custom parameter is allowed
parameters.add_parameter("Additional data", "Example value")

with trsfile.trs_open(
        'trace-set.trs',
        'w',
        engine='TrsEngine',
        headers={
            Header.TRS_VERSION: 2,
            Header.SCALE_X: 1,  # Scaling factor on input data
            Header.SCALE_Y: 1,  # Scaling factor on input data
            Header.DESCRIPTION: 'Sample trace set creation',
            Header.TRACE_SET_PARAMETERS: parameters
        }
) as traces:
    for index in range(len(power)):
        traceparameters = TraceParameterMap()
        # Set of standard trace parameters has been defined; e.g. INPUT (plaintext)
        traceparameters.add_standard_parameter(StandardTraceParameters.INPUT, bytes(tuple(plaintext[index])))
        # However, any custom parameter is allowed
        traceparameters.add_parameter("Additional trace parameter", "Example value")
        traces.append(
            Trace(
                SampleCoding.FLOAT,
                power[index].tolist(),
                traceparameters)
        )

Thanks! It works.

But there still be some a problem that I don't know the usage of trs. Since I don't have the backgroud of .trs.

I can not figure out the read module as above.

Furthermore, Since the transformering the data to trs mainly points to better attack. I would like to introduce more lib like pysca

For more specification:

  1. The access to the trace data
  2. The access to the plaintext data
  3. The api for attacking method
  4. The apo for modeling the medium value like Hammingweight (after_box())

Is there any more basic demo that I can have conceptiona intro to the trs? If so maybe I could get to the same level as I do with numpy lib

Hello @liliaoyuan,

I'm afraid there is no document that I can refer to that gives a conceptual introduction to what a trs file is. However, to give a brief overview: the trs file format is a format for storing data (primarily measurement data) in a way that can be opened in and processed by Inspector, Riscure's tool for side channel testing. Inspector stores individual acquisitions from an oscilloscope as Traces, and adds information like the data sent to the target and the response received from the target to those Traces. Traces are then bundled into a TraceSet, to which additional meta-data is added, like the type of scope used, the time and voltage scales, etc. A trs file contains a single TraceSet. Inspector can perform signal analysis and cryptographic attacks on TraceSets, and often stores its results as TraceSets.

The trs format itself does not provide functionality for performing an attack. For that, one of Inspector's modules needs to be used.

If you would like to use pysca, we cannot help you with that, as the trs file format has no support for using TraceSets in combination with that package. I recommend that you either transform your data to the trs file format and do your attack in Inspector, or do not use the trs file format at all, and use pysca on the data from your numpy arrays.

Got you!
Thanks you in advanced