1
0
mirror of https://github.com/taigrr/arduinolibs synced 2025-01-18 04:33:12 -08:00

Move TransistorNoiseSource to its own library

This commit is contained in:
Rhys Weatherley
2015-04-02 09:24:31 +10:00
parent 86bec72f2f
commit 1d89097948
7 changed files with 10 additions and 2 deletions

View File

@@ -1,258 +0,0 @@
/*
* Copyright (C) 2015 Southern Storm Software, Pty Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "TransistorNoiseSource.h"
#include "RNG.h"
#include "Crypto.h"
#include <Arduino.h>
/**
* \class TransistorNoiseSource TransistorNoiseSource.h <TransistorNoiseSource.h>
* \brief Processes the signal from a transistor-based noise source.
*
* This class processes input from a transistor-based noise source, such as
* that described by <a href="http://robseward.com/misc/RNG2/">Rob Seward</a>.
* See that Web page for full details on how such noise sources work,
* how the output should be used, and caveats for the unwary.
* For convenience, Rob's circuit is reproduced below:
*
* \image html transistor_noise_source.png
*
* The following example shows how to initialize a transistor-based noise
* source and use it with \link RNGClass RNG\endlink. The noise is read
* from the A1 pin on the Arduino and stirred into the random number pool
* on a regular basis. For more information, see the documentation for
* \link RNGClass RNG\endlink.
*
* \code
* #include <Crypto.h>
* #include <RNG.h>
* #include <TransistorNoiseSource.h>
*
* // Noise source to seed the random number generator.
* TransistorNoiseSource noise(A1);
*
* void setup() {
* // Initialize the random number generator with the application tag
* // "MyApp 1.0" and load the previous seed from EEPROM address 500.
* RNG.begin("MyApp 1.0", 500);
*
* // Add the noise source to the list of sources known to RNG.
* RNG.addNoiseSource(noise);
*
* // ...
* }
*
* void loop() {
* // ...
*
* // Perform regular housekeeping on the random number generator.
* RNG.loop();
*
* // ...
* }
* \endcode
*
* \sa \link RNGClass RNG\endlink, NoiseSource, RingOscillatorNoiseSource
*/
/*
Theory of operation:
From Rob Seward's original design we need to find the median of the input
signal. That is, the threshold at which half the signal is below the
threshold (a zero) and the other half is above the threshold (a one).
Rob used a histogram table to find the median which is memory-intensive.
We cannot afford to spend that much memory finding the median.
In this implementation we divide the signal up into "buckets" of 1024
samples. We pick a starting threshold and count the number of ones
within the bucket. If the number of ones is between 45% to 55% of the
total number of samples, then we use that threshold to convert the
bucket into output bits. Otherwise we adjust the threshold up or down,
discard the bucket, and try again.
After a few buckets, the threshold naturally settles at the median without
needing a histogram. The rest of the bucket processing can be done online
with storage needed only for the debiased output bits.
If the input voltage to the noise source is too low to generate noise,
then the delta between the minimum and maximum samples in the bucket will
be quite small. This is used to detect disconnection of the noise source.
No output is generated when the noise source is disconnected.
With 1024 raw input samples we get roughly 256 output bits after
Von Neumann debiasing. As a further check, the output will be discarded
if less than 192 bits are generated. This can happen when the noise source
is connected or disconnected: only part of the bucket is valid.
One of the properties of Rob's circuit design is that over time the median
changes due to environmental factors and component wear. Because we adjust
the threshold from bucket to bucket, it should naturally float up or down
to the new median level as the circuit's properties change.
*/
// Number of ADC values that can be generated by analogRead().
#define ADC_NUM 1024
// Number of samples to collect for a single noise "bucket".
#define SAMPLES_NUM 1024
// Calculate a percentage of the sample bucket size.
#define SAMPLES_PCT(num) ((int)(((long)SAMPLES_NUM) * (num) / 100L))
// Expected spread between the minimum and maximum ADC readings for
// the noise source to be considered as operating correctly.
#define NOISE_SPREAD (ADC_NUM / 8)
// Calibration states.
#define NOISE_NOT_CALIBRATING 0
#define NOISE_CALIBRATING 1
/**
* \brief Constructs a new transitor-based noise source handler.
*
* \param pin The analog input pin that the noise will appear on.
*/
TransistorNoiseSource::TransistorNoiseSource(uint8_t pin)
: threshold(ADC_NUM / 2)
, _pin(pin)
, calState(NOISE_CALIBRATING)
{
// Configure the pin as an analog input with no pull-up.
pinMode(pin, INPUT);
digitalWrite(pin, LOW);
// Start the bit collection routines.
restart();
}
TransistorNoiseSource::~TransistorNoiseSource()
{
restart();
}
bool TransistorNoiseSource::calibrating() const
{
return calState != NOISE_NOT_CALIBRATING;
}
void TransistorNoiseSource::stir()
{
// Keep track of the minimum and maximum while generating data
// so that we can detect when the input voltage falls too low
// for the circuit to generate noise.
int value = analogRead(_pin);
if (value < minValue)
minValue = value;
if (value > maxValue)
maxValue = value;
// Collect two bits of input and remove bias using the Von Neumann method.
// If both bits are the same, then discard both. Otherwise choose one
// of the bits and output that one. We have to do this carefully so that
// instruction timing does not reveal the value of the bit that is chosen.
uint8_t bit = ((threshold - value) >> 15) & 1; // Subtract and extract sign.
if (count & 1) {
if (prevBit ^ bit) {
// The bits are different: add the new bit to the buffer.
if (posn < sizeof(buffer)) {
buffer[posn] = (buffer[posn] << 1) | bit;
if (++bitNum >= 8) {
++posn;
bitNum = 0;
}
}
}
} else {
prevBit = bit;
}
// Keep a count of the number of raw 1 bits.
ones += bit;
// Bail out if we haven't collected enough samples for a full bucket yet.
if (++count < SAMPLES_NUM)
return;
// If the maximum minus the minimum is too small, then there probably
// is no signal or the input voltage is insufficient to generate noise.
// Discard the entire bucket and return to calibration.
if ((maxValue - minValue) < NOISE_SPREAD) {
restart();
calState = NOISE_CALIBRATING;
threshold = ADC_NUM / 2; // Reacquire threshold when the signal returns.
return;
}
// If the number of 1's is between 45% and 55% of the total count,
// then we have a good bucket. The threshold is at an appropriate level.
if (ones >= SAMPLES_PCT(45) && ones <= SAMPLES_PCT(55)) {
if (posn >= (sizeof(buffer) * 3 / 4)) {
// The buffer is at least three-quarters full of debiased bits
// so pass them onto output(). There may be less bits if we
// lost or gained the signal half-way through the bucket.
// Credit 4 bits of entropy for every 8 bits of output.
output(buffer, posn, posn * 4);
}
restart();
calState = NOISE_NOT_CALIBRATING;
return;
}
// The threshold is not close enough to the mid-point of the signal.
// Adjust the threshold, discard the bucket, and try again.
if (ones < SAMPLES_PCT(25) || ones > SAMPLES_PCT(75)) {
// We are a long way away from the mid-point, so move the threshold
// by a large amount based on the delta to get closer quicker.
threshold -= (SAMPLES_PCT(50) - ones) / 8;
} else if (ones < SAMPLES_PCT(50)) {
// Not enough ones so move the threshold down a bit.
--threshold;
} else {
// Too many ones so move the threshold up a bit.
++threshold;
}
if (threshold < 0)
threshold = 0;
else if (threshold >= ADC_NUM)
threshold = ADC_NUM - 1;
restart();
calState = NOISE_CALIBRATING;
}
/**
* \brief Restarts the bit collection process for the next bucket.
*/
void TransistorNoiseSource::restart()
{
clean(buffer);
prevBit = 0;
posn = 0;
bitNum = 0;
minValue = ADC_NUM - 1;
maxValue = 0;
count = 0;
ones = 0;
}

View File

@@ -1,55 +0,0 @@
/*
* Copyright (C) 2015 Southern Storm Software, Pty Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef CRYPTO_TRANSISTORNOISESOURCE_H
#define CRYPTO_TRANSISTORNOISESOURCE_H
#include <inttypes.h>
#include "NoiseSource.h"
class TransistorNoiseSource : public NoiseSource
{
public:
explicit TransistorNoiseSource(uint8_t pin);
virtual ~TransistorNoiseSource();
bool calibrating() const;
void stir();
private:
int threshold;
uint8_t _pin;
uint8_t prevBit;
uint8_t posn;
uint8_t bitNum;
uint8_t calState;
uint8_t buffer[32];
int minValue;
int maxValue;
int count;
int ones;
void restart();
};
#endif

View File

@@ -1,44 +0,0 @@
// This example dumps the raw data from a transistor noise source
// without any of the whitening normally performed by the RNG class.
#include <Crypto.h>
#include <TransistorNoiseSource.h>
char const hexchars[] = "0123456789ABCDEF";
class RawNoiseSource : public TransistorNoiseSource
{
public:
RawNoiseSource(uint8_t pin) : TransistorNoiseSource(pin) {}
protected:
void output(const uint8_t *data, size_t len, unsigned int credit)
{
for (size_t posn = 0; posn < len; ++posn) {
uint8_t value = data[posn];
Serial.print(hexchars[(value >> 4) & 0x0F]);
Serial.print(hexchars[value & 0x0F]);
}
Serial.println();
}
};
RawNoiseSource noise(A1);
bool calibrating = true;
void setup() {
Serial.begin(9600);
Serial.println();
Serial.println("calibrating");
}
void loop() {
noise.stir();
bool nowCalibrating = noise.calibrating();
if (nowCalibrating != calibrating) {
calibrating = nowCalibrating;
if (calibrating)
Serial.println("calibrating");
}
}

View File

@@ -2,13 +2,18 @@ AES128 KEYWORD1
AES192 KEYWORD1
AES256 KEYWORD1
ChaCha KEYWORD1
ChaChaPoly KEYWORD1
BLAKE2b KEYWORD1
BLAKE2s KEYWORD1
SHA1 KEYWORD1
SHA256 KEYWORD1
SHA512 KEYWORD1
SHA3_256 KEYWORD1
SHA3_512 KEYWORD1
KeccakCore KEYWORD1
Poly1305 KEYWORD1
GHASH KEYWORD1
Curve25519 KEYWORD1
@@ -16,18 +21,19 @@ CBC KEYWORD1
CFB KEYWORD1
CTR KEYWORD1
OFB KEYWORD1
GCM KEYWORD1
RingOscillatorNoiseSource KEYWORD1
RNG KEYWORD1
TransistorNoiseSource KEYWORD1
keySize KEYWORD2
ivSize KEYWORD2
tagSize KEYWORD2
setKey KEYWORD2
setIV KEYWORD2
encrypt KEYWORD2
decrypt KEYWORD2
clear KEYWORD2
addAuthData KEYWORD2
hashSize KEYWORD2
blockSize KEYWORD2

View File

@@ -1,203 +0,0 @@
#FIG 3.2 Produced by xfig version 3.2.5c
Landscape
Center
Metric
A4
100.00
Single
-2
1200 2
0 32 #404040
0 33 #808080
0 34 #c0c0c0
0 35 #e0e0e0
0 36 #808080
0 37 #c0c0c0
0 38 #e0e0e0
0 39 #444444
0 40 #8e8f8e
6 3465 4275 3690 4590
5 1 0 1 0 -1 0 0 -1 0.000 1 0 0 0 3600.000 4600.000 3510 4480 3600 4450 3690 4480
2 1 0 1 0 -1 0 0 -1 0.000 0 1 -1 0 0 2
3600 4450 3600 4590
2 1 0 1 0 -1 0 0 -1 0.000 0 1 -1 0 0 2
3510 4410 3690 4410
2 1 0 1 0 -1 0 0 -1 0.000 0 1 -1 0 0 2
3600 4410 3600 4275
2 1 0 1 0 -1 0 0 -1 0.000 0 1 -1 0 0 2
3536 4304 3536 4374
2 1 0 1 0 -1 0 0 -1 0.000 0 1 -1 0 0 2
3506 4339 3566 4339
-6
6 4725 4500 5220 4950
1 3 0 1 0 -1 0 0 -1 0.000 1 0.0000 4995 4725 186 186 4995 4725 5040 4905
2 1 0 1 0 -1 0 0 20 0.000 0 0 -1 0 0 4
5095 4870 5050 4780 5005 4825 5095 4870
2 1 0 1 0 -1 0 0 -1 0.000 0 0 -1 0 0 2
4950 4725 5175 4950
2 1 0 1 0 -1 0 0 -1 0.000 0 0 -1 0 0 2
4950 4725 5175 4500
2 1 0 1 0 -1 0 0 -1 0.000 0 0 -1 0 0 2
4950 4590 4950 4860
2 1 0 1 0 -1 0 0 -1 0.000 0 0 -1 0 0 2
4950 4725 4725 4725
-6
6 4680 3600 4770 4050
2 1 0 1 0 -1 0 0 -1 0.000 0 0 -1 0 0 2
4725 3955 4725 4050
2 1 0 1 0 -1 0 0 -1 0.000 0 0 -1 0 0 7
4725 3690 4685 3717 4765 3771 4685 3825 4765 3879 4685 3933
4725 3960
2 1 0 1 0 -1 0 0 -1 0.000 0 0 -1 0 0 2
4725 3600 4725 3695
-6
6 4230 4500 4725 4950
1 3 0 1 0 -1 0 0 -1 0.000 1 0.0000 4455 4725 186 186 4455 4725 4410 4545
2 1 0 1 0 -1 0 0 20 0.000 0 0 -1 0 0 4
4355 4580 4400 4670 4445 4625 4355 4580
2 1 0 1 0 -1 0 0 -1 0.000 0 0 -1 0 0 2
4500 4725 4275 4500
2 1 0 1 0 -1 0 0 -1 0.000 0 0 -1 0 0 2
4500 4725 4275 4950
2 1 0 1 0 -1 0 0 -1 0.000 0 0 -1 0 0 2
4500 4860 4500 4590
2 1 0 1 0 -1 0 0 -1 0.000 0 0 -1 0 0 2
4500 4725 4725 4725
-6
6 5490 4185 5805 4365
2 1 0 1 0 -1 0 0 -1 0.000 0 0 -1 0 0 2
5625 4275 5490 4275
2 1 0 1 0 -1 0 0 -1 0.000 0 0 -1 0 0 2
5670 4275 5805 4275
2 1 0 1 0 -1 0 0 -1 0.000 0 0 -1 0 0 2
5625 4365 5625 4185
2 1 0 1 0 -1 0 0 -1 0.000 0 0 -1 0 0 2
5670 4365 5670 4185
-6
6 6075 4050 6570 4500
1 3 0 1 0 -1 0 0 -1 0.000 1 0.0000 6345 4275 186 186 6345 4275 6390 4455
2 1 0 1 0 -1 0 0 20 0.000 0 0 -1 0 0 4
6445 4420 6400 4330 6355 4375 6445 4420
2 1 0 1 0 -1 0 0 -1 0.000 0 0 -1 0 0 2
6300 4275 6525 4500
2 1 0 1 0 -1 0 0 -1 0.000 0 0 -1 0 0 2
6300 4275 6525 4050
2 1 0 1 0 -1 0 0 -1 0.000 0 0 -1 0 0 2
6300 4140 6300 4410
2 1 0 1 0 -1 0 0 -1 0.000 0 0 -1 0 0 2
6300 4275 6075 4275
-6
6 5895 3600 5985 4050
2 1 0 1 0 -1 0 0 -1 0.000 0 0 -1 0 0 2
5940 3955 5940 4050
2 1 0 1 0 -1 0 0 -1 0.000 0 0 -1 0 0 7
5940 3690 5900 3717 5980 3771 5900 3825 5980 3879 5900 3933
5940 3960
2 1 0 1 0 -1 0 0 -1 0.000 0 0 -1 0 0 2
5940 3600 5940 3695
-6
6 3555 3330 3645 3420
1 3 0 1 0 -1 0 0 20 0.000 1 0.0000 3600 3375 30 30 3600 3375 3600 3405
-6
6 4680 3330 4770 3420
1 3 0 1 0 -1 0 0 20 0.000 1 0.0000 4725 3375 30 30 4725 3375 4725 3405
-6
6 5895 3330 5985 3420
1 3 0 1 0 -1 0 0 20 0.000 1 0.0000 5940 3375 30 30 5940 3375 5940 3405
-6
6 5895 4230 5985 4320
1 3 0 1 0 -1 0 0 20 0.000 1 0.0000 5940 4275 30 30 5940 4275 5940 4305
-6
6 5130 4230 5220 4320
1 3 0 1 0 -1 0 0 20 0.000 1 0.0000 5175 4275 30 30 5175 4275 5175 4305
-6
6 4680 4230 4770 4320
1 3 0 1 0 -1 0 0 20 0.000 1 0.0000 4725 4275 30 30 4725 4275 4725 4305
-6
6 5130 5355 5220 5445
1 3 0 1 0 -1 0 0 20 0.000 1 0.0000 5175 5400 30 30 5175 5400 5175 5430
-6
6 3555 5355 3645 5445
1 3 0 1 0 -1 0 0 20 0.000 1 0.0000 3600 5400 30 30 3600 5400 3600 5430
-6
6 6480 5355 6570 5445
1 3 0 1 0 -1 0 0 20 0.000 1 0.0000 6525 5400 30 30 6525 5400 6525 5430
-6
6 7155 4635 7245 5085
2 1 0 1 0 -1 0 0 -1 0.000 0 0 -1 0 0 2
7200 4990 7200 5085
2 1 0 1 0 -1 0 0 -1 0.000 0 0 -1 0 0 7
7200 4725 7160 4752 7240 4806 7160 4860 7240 4914 7160 4968
7200 4995
2 1 0 1 0 -1 0 0 -1 0.000 0 0 -1 0 0 2
7200 4635 7200 4730
-6
6 7155 3510 7245 3960
2 1 0 1 0 -1 0 0 -1 0.000 0 0 -1 0 0 2
7200 3865 7200 3960
2 1 0 1 0 -1 0 0 -1 0.000 0 0 -1 0 0 7
7200 3600 7160 3627 7240 3681 7160 3735 7240 3789 7160 3843
7200 3870
2 1 0 1 0 -1 0 0 -1 0.000 0 0 -1 0 0 2
7200 3510 7200 3605
-6
6 7155 4005 7245 4095
1 3 0 1 0 -1 0 0 20 0.000 1 0.0000 7200 4050 30 30 7200 4050 7200 4080
-6
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
5175 4950 5175 5400
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
3600 4545 3600 5400
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
3600 4275 3600 3375
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
4725 4050 4725 4275
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
4275 4950 4275 5085
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 4
4275 4500 4275 4275 5175 4275 5175 4500
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
4725 3600 4725 3375
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
6525 4500 6525 5400
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
5490 4275 5130 4275
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
5760 4275 6120 4275
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
5940 4050 5940 4275
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
5940 3645 5940 3375
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
7200 5085 7200 5400
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
7200 3510 7200 3375
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
6525 4050 7650 4050
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
7200 3915 7200 4635
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2
8 1 1.00 60.00 120.00
2925 5400 7200 5400
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2
8 1 1.00 60.00 120.00
2925 3375 7200 3375
4 0 0 50 -1 0 12 0.0000 4 135 420 3015 4455 10uF\001
4 0 0 50 -1 0 12 0.0000 4 135 345 6705 3780 10K\001
4 0 0 50 -1 0 12 0.0000 4 135 390 6705 4905 4.7K\001
4 0 0 50 -1 0 12 0.0000 4 135 435 5400 3870 1.5M\001
4 0 0 50 -1 0 12 0.0000 4 135 390 4185 3915 4.7K\001
4 0 0 50 -1 0 12 0.0000 4 135 345 3060 4680 25V\001
4 0 0 50 -1 0 12 0.0000 4 135 525 5400 4545 100nF\001
4 0 0 50 -1 0 12 0.0000 4 165 240 5265 4770 Q2\001
4 0 0 50 -1 0 12 0.0000 4 165 240 6615 4320 Q3\001
4 0 0 50 -1 0 12 0.0000 4 135 270 3915 5175 NC\001
4 0 0 50 -1 0 12 0.0000 4 165 240 3960 4770 Q1\001
4 0 0 50 -1 0 12 0.0000 4 135 405 2385 5490 GND\001
4 0 0 50 -1 0 12 0.0000 4 180 1185 7785 4005 To Analog Pin\001
4 0 0 50 -1 0 12 0.0000 4 135 960 7875 4230 On Arduino\001
4 0 0 50 -1 0 12 0.0000 4 180 3735 3330 5805 All transistors: BC548, 2N3904, or equivalent\001
4 0 0 50 -1 0 12 0.0000 4 180 4440 3015 6075 Collector of Q1 must be left not connected to anything\001
4 0 0 50 -1 0 12 0.0000 4 135 810 2070 3600 10 to 15V\001
4 0 0 50 -1 0 12 0.0000 4 135 330 2295 3375 VIN\001

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB