Python 3 Library to access the NIST Randomness Beacon
Project description
Python NIST Randomness Beacon
WARNING: DO NOT USE BEACON GENERATED VALUES AS SECRET CRYPTOGRAPHIC KEYS.
Installation
Prerequisites
A required library pycrypto
is used with nistbeacon
.
Ubuntu, and other Linux-based users should have python3-dev
installed.
apt-get install python3-dev
Installing nistbeacon
To install the beacon library, simply use pip
:
pip install nistbeacon
Beacon Usage
It is easy to use the beacon. Most queries are performed through
NistBeacon
which produces NistBeaconValue
objects.
Beacon Sample Code
from nistbeacon import NistBeacon
# In the examples below I will be using 1447873020
# as my <timestamp> when required
# Current Record (or next closest)
# https://beacon.nist.gov/rest/record/<timestamp>
record = NistBeacon.get_record(1447873020)
# Previous Record
# https://beacon.nist.gov/rest/record/previous/<timestamp>
prev_record = NistBeacon.get_previous(1447873020)
# Next Record
# https://beacon.nist.gov/rest/record/next/<timestamp>
next_record = NistBeacon.get_next(1447873020)
# First Record
# https://beacon.nist.gov/rest/record/1378395540
first_record = NistBeacon.get_first_record(download=True)
# Last Record
# https://beacon.nist.gov/rest/record/last
last_record = NistBeacon.get_last_record()
# Verify the record and the record chain
record_chain_result = NistBeacon.chain_check(1447873020)
Beacon Methods
@classmethod
def chain_check(cls, timestamp: int) -> bool:
"""
Given a record timestamp, verify the chain integrity.
:param timestamp: UNIX time / POSIX time / Epoch time
:return: 'True' if the timestamp fits the chain. 'False' otherwise.
"""
@classmethod
def get_first_record(
cls,
download: bool=False
) -> NistBeaconValue:
"""
Get the first (oldest) record available. Since the first record
IS a known value in the system we can load it from constants.
:param download: 'True' will always reach out to NIST to get the
first record. 'False' returns a local copy.
:return: The first beacon value. 'None' otherwise.
"""
@classmethod
def get_last_record(cls) -> NistBeaconValue:
"""
Get the last (newest) record available.
:return: The last beacon value. 'None' otherwise.
"""
@classmethod
def get_next(cls, timestamp: int) -> NistBeaconValue:
"""
Given a record timestamp, get the next record available.
:param timestamp: UNIX time / POSIX time / Epoch time
:return: The next beacon value if available. 'None' otherwise.
"""
@classmethod
def get_previous(cls, timestamp: int) -> NistBeaconValue:
"""
Given a record timestamp, get the previous record available.
:param timestamp: UNIX time / POSIX time / Epoch time
:return: The previous beacon value if available. 'None; otherwise
"""
@classmethod
def get_record(cls, timestamp: int) -> NistBeaconValue:
"""
Get a specific record (or next closest)
:param timestamp: UNIX time / POSIX time / Epoch time
:return: The requested beacon value if available. 'None' otherwise.
"""
Beacon Value
The NistBeaconValue
objects act as basic python objects.
As one would expect, there are a number of properties and methods available
on it.
Beacon Value Instance
"""
:param version:
Reported NIST randomness beacon version
:param frequency:
The time interval, in seconds, between expected records
:param timestamp:
The time the seed value was generated as the number of
seconds since January 1, 1970
:param seed_value:
A seed value represented as a 64 byte (512-bit) hex string
value
:param previous_output_value:
The SHA-512 hash value for the previous record - 64 byte hex
string
:param signature_value:
A digital signature (RSA) computed over (in order): version,
frequency, timeStamp, seedValue, previousHashValue, statusCode
Note: Except for version, the hash is on the byte
representations and not the string representations of the data
values
:param output_value:
The SHA-512 hash of the signatureValue as a 64 byte hex string
:param status_code:
The status code value:
0 - Chain intact, values all good
1 - Start of a new chain of values, previous hash value
will be all zeroes
2 - Time between values is greater than the frequency, but
the chain is still intact
"""
Beacon Value Properties
@property
def frequency(self) -> int:
"""
:return: The time interval, in seconds, between expected records
"""
@property
def json(self) -> str:
"""
:return: The JSON representation of the beacon, as a string
"""
@property
def output_value(self) -> str:
"""
:return: The SHA-512 hash of the signatureValue as a 64 byte hex string
"""
@property
def previous_output_value(self) -> str:
"""
:return:
The SHA-512 hash value for the previous record - 64 byte hex
string
"""
@property
def pseudo_random(self) -> Random:
"""
:return:
A python `random.Random` object that has been seeded with
the value's `output_value`. This is a pseudo-random
number generator
"""
@property
def seed_value(self) -> str:
"""
:return:
A seed value represented as a 64 byte (512-bit) hex string
value
"""
@property
def signature_value(self) -> str:
"""
:return:
A digital signature (RSA) computed over (in order): version,
frequency, timeStamp, seedValue, previousHashValue, statusCode
Note: Except for version, the hash is on the byte
representations and not the string representations of the data
values
"""
@property
def status_code(self) -> str:
"""
:return:
The status code value:
0 - Chain intact, values all good
1 - Start of a new chain of values, previous hash value
will be all zeroes
2 - Time between values is greater than the frequency, but
the chain is still intact
"""
@property
def timestamp(self) -> int:
"""
:return:
The time the seed value was generated as the number of
seconds since January 1, 1970
"""
@property
def valid_signature(self) -> bool:
"""
Shows the result of signature verification
First, required records (version, frequency, timestamp,
seed_value, previous_output_value) are packed together to form
a message. This message is then checked against the record's reported
signature field WITH the known NIST public key.
Second, the signature value is independently ran through a SHA512
hash. The result of this operation SHOULD equal the record's reported
output_value field.
As long as the result of the 'First' step and'ed with the 'Second'
step, the record is considered valid.
:return: 'True' if this record is valid. 'False' otherwise
"""
@property
def version(self) -> str:
"""
:return: Reported NIST randomness beacon version
"""
@property
def xml(self) -> str:
"""
:return: The XML representation of the beacon, as a string
"""
Beacon Value Methods
@classmethod
def from_json(cls, input_json: str):
"""
Convert a string of JSON which represents a NIST randomness beacon
value into a 'NistBeaconValue' object.
:param input_json: JSON to build a 'Nist RandomnessBeaconValue' from
:return: A 'NistBeaconValue' object, 'None' otherwise
"""
@classmethod
def from_xml(cls, input_xml: str):
"""
Convert a string of XML which represents a NIST Randomness Beacon value
into a 'NistBeaconValue' object.
:param input_xml: XML to build a 'NistBeaconValue' from
:return: A 'NistBeaconValue' object, 'None' otherwise
"""
Contributing
Please refer to the CONTRIBUTING document on GitHub
Project Health
Branch |
Build Status |
Coverage Status |
---|---|---|
Master |
||
Release |
References
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.