QWQNG.QNG 3.6 API
Table of Contents
Introduction
Requirements
The QWQNG.QNG ActiveX control requires Windows 7 or later.
Description
QNG hardware is accessed using the QWQNG.QNG ActiveX control. As such, it is widely supported among different Windows environments and languages. If you do not find a basic example suitable for your particular environment, consult your developers guide on how to use ActiveX controls.
The quickest way to get started is by looking at the properties for reading random numbers from the QNG device and trying the example code given for each property. The properties for reading random numbers from the device are RandInt32, RandUniform, RandNormal, and RandBytes. The example code is meant to concisely demonstrate the use of the QWQNG.QNG ActiveX methods and properties and thus does not adhere to best coding practices, such as exception/error handling, etc.
Notes
The QWQNG.QNG ActiveX control version 3.6 is drop-in compatible with client applications that were designed for previous versions of the ActiveX control.
QNG hardware constantly reports hardware run-time test results. If run-time test results appear questionable, the QWQNG.QNG ActiveX control immediately shuts down the hardware and reports the exception. See the section on Runtime Testing for more information.
The QWQNG.QNG control provides custom HRESULT codes on every method or property call. HRESULT codes provide exception/error detail. If any error condition is detected, the hardware device will be shut down and the appropriate HRESULT code will be passed to the caller. The HRESULT error code will persist until a Reset() call is issued. The Reset() call will attempt to restart the hardware and clear the error code. See the section on Error Handling for examples and more information.
During a programming session, a programming environment typically sets the Ambient Properties for an ActiveX control to design mode. In design mode the QWQNG.QNG control will return default values for RandInt32 (123456789), RandUniform (0.123456789), RandNormal (1.23456789) and RandBytes (1234567890123…). If the QWQNG.QNG control returns these values at run-time, please make sure the User Mode Ambient Property is set to TRUE at run-time. This should normally not be an issue, however.
Support
Contact ComScire via email, phone, or mail regarding any support issues. Please visit our Contact Us page to obtain our latest support contact information.
API Reference
RandInt32
HRESULT RandInt32([out, retval] LONG* pVal)
Returns
Random 32 bit integer as LONG (VT_I4)
Remarks
RandInt32 is a COM property that returns a 32 bit random integer. Each RandInt32 integer contains 32 bits of entropy.
C++ Example
// #import directive using full path to "QWQNG.dll"
#import "QWQNG.dll" no_namespace named_guids
int main() {
CoInitialize(NULL);
IQNGPtr qng = 0;
qng.CreateInstance(CLSID_QNG);
int rand32 = qng->RandInt32;
printf("%i\n", rand32);
return 0;
}
C# Example
// requires reference to "ComScire QNG Control Library 3.6"
using System;
class Program {
static void Main(string[] args) {
QWQNG.QNG qng = new QWQNG.QNG();
int rand32 = qng.RandInt32;
Console.WriteLine(rand32.ToString());
}
}
Python Example
# requires PyWin32 extensions
import win32com.client
qng = win32com.client.Dispatch("QWQNG.QNG")
rand32 = qng.RandInt32
print rand32
RandUniform
HRESULT RandUniform([out, retval] DOUBLE* pVal)
Returns
Random uniform number [0,1) as DOUBLE (VT_R8)
Remarks
RandUniform is a COM property that returns a double float that is randomly selected from a uniform distribution. Each RandUniform number contains 48 bits of entropy.
C++ Example
// #import directive using full path to "QWQNG.dll"
#import "QWQNG.dll" no_namespace named_guids
int main() {
CoInitialize(NULL);
IQNGPtr qng = 0;
qng.CreateInstance(CLSID_QNG);
double randuniform = qng->RandUniform;
printf("%f\n", randuniform);
return 0;
}
C# Example
// requires reference to "ComScire QNG Control Library 3.6"
using System;
class Program {
static void Main(string[] args) {
QWQNG.QNG qng = new QWQNG.QNG();
double randuniform = qng.RandUniform;
Console.WriteLine(randuniform.ToString());
}
}
Python Example
# requires PyWin32 extensions
import win32com.client
qng = win32com.client.Dispatch("QWQNG.QNG")
randuniform = qng.RandUniform
print randuniform
RandNormal
HRESULT RandNormal([out, retval] DOUBLE* pVal
Returns
Random normal number with mean zero and standard deviation one as DOUBLE (VT_R8)
Remarks
RandNormal is a COM property that returns a double float that is randomly selected from a normal distribution. RandNormal numbers are produced by transforming uniform numbers, with 48 bits of entropy each, into normal numbers using the Box-Muller method.
C++ Example
// #import directive using full path to "QWQNG.dll"
#import "QWQNG.dll" no_namespace named_guids
int main() {
CoInitialize(NULL);
IQNGPtr qng = 0;
qng.CreateInstance(CLSID_QNG);
double randnormal = qng->RandNormal;
printf("%f\n", randnormal);
return 0;
}
C# Example
// requires reference to "ComScire QNG Control Library 3.6"
using System;
class Program {
static void Main(string[] args) {
QWQNG.QNG qng = new QWQNG.QNG();
double randnormal = qng.RandNormal;
Console.WriteLine(randnormal.ToString());
}
}
Python Example
# requires PyWin32 extensions
import win32com.client
qng = win32com.client.Dispatch("QWQNG.QNG")
randnormal = qng.RandNormal
print randnormal
RandBytes
HRESULT RandBytes([in] LONG Length, [out, retval] VARIANT* pVal)
Parameters
Length: Number of bytes to be returned from RandBytes. Must not exceed 8192 for generator output rate of 32 Mbps or less, 65536 for generator output rate of 64 or 128 Mbps.
Returns
Byte array as VARIANT SAFEARRAY of BYTES (VT_ARRAY of VT_U1)
Remarks
RandBytes is a COM property that returns a byte array of random bytes. Each byte contains 8 bits of entropy. If Length exceeds maximum allowed requested bytes, the control will return the QNG_E_IO_ARRAY_OVERSIZED error code. For information on using Variant SAFEARRAY’s, please consult documentation specific to your programming environment.
C++ Example
// #import directive using full path to "QWQNG.dll"
#import "QWQNG.dll" no_namespace named_guids
int main() {
CoInitialize(NULL);
IQNGPtr qng = 0;
qng.CreateInstance(CLSID_QNG);
_variant_t randvt = qng->RandBytes[10];
VARIANT randvariant = randvt.GetVARIANT();
int bytecount = randvariant.parray->rgsabound[0].cElements
- randvariant.parray->rgsabound[0].lLbound;
char* randbyte;
SafeArrayAccessData(randvariant.parray, (void**)&randbyte);
for (int i=0; i
C# Example
// requires reference to "ComScire QNG Control Library 3.6"
using System;
class Program {
static void Main(string[] args) {
QWQNG.QNG qng = new QWQNG.QNG();
byte[] randbytes = (byte[])qng.get_RandBytes(10);
foreach (byte b in randbytes)
Console.Write("{0:X} ", b);
Console.WriteLine();
}
}
Python Example
# requires PyWin32 extensions
import win32com.client
qng = win32com.client.Dispatch("QWQNG.QNG")
randbytes = qng.RandBytes(10)
print randbytes
Clear
HRESULT Clear(VOID)
Remarks
Clear is a COM method that purges internal data buffers. If random data is not continuously consumed, random data will remain available in internal buffers. A call to Clear will remove “stale” data from the buffers.
C++ Example
// #import directive using full path to "QWQNG.dll"
#import "QWQNG.dll" no_namespace named_guids
int main() {
CoInitialize(NULL);
IQNGPtr qng = 0;
qng.CreateInstance(CLSID_QNG);
// clear random data sitting in internal buffers
qng->Clear();
return 0;
}
C# Example
// requires reference to "ComScire QNG Control Library 3.6"
using System;
class Program {
static void Main(string[] args) {
QWQNG.QNG qng = new QWQNG.QNG();
// clear random data sitting in internal buffers
qng.Clear();
}
}
Python Example
# requires PyWin32 extensions
import win32com.client
qng = win32com.client.Dispatch("QWQNG.QNG")
# clear random data sitting in internal buffers
qng.Clear()
Reset
HRESULT Clear(VOID)
Remarks
Reset() is a COM method that clears the buffers and resets the hardware device.
C++ Example
// #import directive using full path to "QWQNG.dll"
#import "QWQNG.dll" no_namespace named_guids
int main() {
CoInitialize(NULL);
IQNGPtr qng = 0;
qng.CreateInstance(CLSID_QNG);
// attempt a complete hardware reset
qng->Reset();
return 0;
}
C# Example
// requires reference to "ComScire QNG Control Library 3.6"
using System;
class Program {
static void Main(string[] args) {
QWQNG.QNG qng = new QWQNG.QNG();
// attempt a complete hardware reset
qng.Reset();
}
}
Python Example
# requires PyWin32 extensions
import win32com.client
qng = win32com.client.Dispatch("QWQNG.QNG")
# attempt a complete hardware reset
qng.Reset()
DeviceId
HRESULT DeviceId([out, retval] BSTR* devId)
Returns
Serial number as a binary string.
Remarks
DeviceId is a COM property that returns a the device serial number as a BSTR.
C++ Example
// #import directive using full path to "QWQNG.dll"
#import "QWQNG.dll" no_namespace named_guids
int main() {
CoInitialize(NULL);
IQNGPtr qng = 0;
qng.CreateInstance(CLSID_QNG);
BSTR deviceId = qng->DeviceId;
printf("%S\n", deviceId);
return 0;
}
C# Example
// requires reference to "ComScire QNG Control Library 3.6"
using System;
class Program {
static void Main(string[] args) {
QWQNG.QNG qng = new QWQNG.QNG();
string deviceId = qng.DeviceId;
Console.WriteLine(deviceId);
}
}
Python Example
# requires PyWin32 extensions
import win32com.client
qng = win32com.client.Dispatch("QWQNG.QNG")
deviceId = qng.DeviceId
print deviceId
RuntimeInfo
HRESULT RuntimeInfo([out, retval] VARIANT* runtimeInfo)
Returns
Float array as VARIANT SAFEARRAY of 32 bit floating point numbers (VT_ARRAY of VT_R4)
Remarks
RuntimeInfo is a COM property that returns a SAFEARRAY of 17 floating point numbers. The numbers indicate the internal runtime state. Assuming a zero index based array:
runtimeInfo[0]: General statistical status. A zero (0) indicates that all internal statistics
are within expected ranges and a minus one (-1) indicates an exception.
runtimeInfo[1]: Entropy H(P) of final output channel.
runtimeInfo[2]: Predictability value (P) of final output channel.
runtimeInfo[3]: Bias of final output channel.
runtimeInfo[4]: 1st order serial correlation of final output channel.
runtimeInfo[5]: Entropy H(P) of 1st raw generator channel.
runtimeInfo[6]: Predictability value (P) of 1st raw generator channel.
runtimeInfo[7]: Bias of 1st raw generator channel.
runtimeInfo[8]: 1st order serial correlation of 1st raw generator channel.
runtimeInfo[9]: Entropy H(P) of 2nd raw generator channel.
runtimeInfo[10]: Predictability value (P) of 2nd raw generator channel.
runtimeInfo[11]: Bias of 2nd raw generator channel.
runtimeInfo[12]: 1st order serial correlation of 2nd raw generator channel.
runtimeInfo[13]: Entropy H(P) of 3rd raw generator channel.
runtimeInfo[14]: Predictability value (P) of 3rd raw generator channel.
runtimeInfo[15]: Bias of 3rd raw generator channel.
runtimeInfo[16]: 1st order serial correlation of 3rd raw generator channel.
RuntimeInfo is not supported on devices prior to the model R2000KU.
C++ Example
// #import directive using full path to "QWQNG.dll"
#import "QWQNG.dll" no_namespace named_guids
int main() {
CoInitialize(NULL);
IQNGPtr qng = 0;
qng.CreateInstance(CLSID_QNG);
_variant_t randvt = qng->RuntimeInfo;
VARIANT randvariant = randvt.GetVARIANT();
int infoCount = randvariant.parray->rgsabound[0].cElements
- randvariant.parray->rgsabound[0].lLbound;
float* runtimeInfo;
SafeArrayAccessData(randvariant.parray, (void**)&runtimeInfo);
for (int i=0; i
C# Example
// requires reference to "ComScire QNG Control Library 3.6"
using System;
class Program {
static void Main(string[] args) {
QWQNG.QNG qng = new QWQNG.QNG();
float[] runtimeInfo = (float[])qng.RuntimeInfo;
for (int i=0; i
Python Example
# requires PyWin32 extensions
import win32com.client
qng = win32com.client.Dispatch("QWQNG.QNG")
runtimeInfo = qng.runtimeInfo
print runtimeInfo
Diagnostics
HRESULT Diagnostics([in] LONG dxCode, [out, retval] VARIANT* dxInfo)
Returns
Byte array as VARIANT SAFEARRAY of BYTES (VT_ARRAY of VT_U1)
Remarks
Diagnostics is a COM property that returns a SAFEARRAY of 128 bytes for a specified internal pre-output raw data channel on a specific level of processing. Diagnostics provides insight into three entropy combining levels of processing in PureQuantum® (PQ) and the final raw output stream in CryptoStrong™ (CS) generators. Each successive level, beginning with level 1, combines more entropy per bit towards the final output. The final output itself exceeds NIST defined full entropy without utilizing correction, whitening, or conditioning. Note that low-level pre-output data is not expected to look perfectly random. Therefore, data gathered from Diagnostics should never be used in random data consuming applications. The intention of Diagnostics is to allow measurements into the the pre-output generation levels to follow and confirm theoretical generation models. More information on PureQuantum® and CryptoStrong™ generation internals can be found in whitepapers published on the ComScire website. Diagnostics allows access to three levels of pre-output generation with three channels per level, and the final combined output for CryptoStrong™ generators. The following lists corresponding hex Diagnostics codes (dxCode) for each level and channel:
Level 1, Channel 1: 0x10
Level 1, Channel 2: 0x11
Level 1, Channel 3: 0x12
Level 2, Channel 1: 0x13
Level 2, Channel 2: 0x14
Level 2, Channel 3: 0x15
Level 3, Channel 1: 0x16
Level 3, Channel 2: 0x17
Level 3, Channel 3: 0x18
Final Output (CS Model only): 0x19
Note that there may be other undocumented Diagnostics codes (dxCode). However, using these codes may produce unexpected outputs or results. Nonetheless, random data obtained through the random API calls (RandInt32, RandUniform, RandNormal, RandBytes) is entirely unaffected by Diagnostics calls. Diagnostics is not supported on devices prior to the PureQuantum® (PQ) and CryptoStrong™ (CS) models. Final output stream (dxCode: 0x19) is only available in CryptoStrong™ models.
C++ Example
// #import directive using full path to "QWQNG.dll"
#import "QWQNG.dll" no_namespace named_guids
int main() {
CoInitialize(NULL);
IQNGPtr qng = 0;
qng.CreateInstance(CLSID_QNG);
// Level 2, Channel 3 dx data
unsigned char controlWord = 0x15;
_variant_t randvt = qng->Diagnostics(controlWord);
VARIANT randvariant = randvt.GetVARIANT();
int byteCount = randvariant.parray->rgsabound[0].cElements
- randvariant.parray->rgsabound[0].lLbound;
unsigned char* dxData;
SafeArrayAccessData(randvariant.parray, (void**)&dxData);
for (int i=0; i
C# Example
// requires reference to "ComScire QNG Control Library 3.6"
using System;
class Program {
static void Main(string[] args) {
QWQNG.QNG qng = new QWQNG.QNG();
// Level 2, Channel 3 dx data
byte controlWord = 0x15;
byte[] dxData = (float[])qng.Diagnostics(controlWord);
foreach (byte b in dxData)
Console.Write("{0:X} ", b);
Console.WriteLine();
}
}
Python Example
# requires PyWin32 extensions
import win32com.client
qng = win32com.client.Dispatch("QWQNG.QNG")
# Level 2, Channel 3 dx data
dxData = qng.Diagnostics(0x15)
print dxData
Error Handling
The QWQNG.QNG ActiveX control returns a set of custom HRESULT error codes. Check your programming language/environment documentation to get more information on how to handle ActiveX errors or exceptions. All error conditions will persist until cleared by a succesful Reset method call.
HResults Codes
QNG_S_OK 00044400h
QNG device reports success.
QNG_E_GENERAL_FAILURE 80044401h
QNG general error.
QNG_E_IO_ERROR 80044402h
QNG I/O error.
QNG_E_IO_TIMEOUT 80044403h
QNG I/O request has timed out.
QNG_E_IO_ARRAY_OVERSIZED 80044404h
QNG read array size exceeds max size.
QNG_E_STATS_EXCEPTION 80044406h
QNG test statistics exception.
QNG_E_STATS_UNSUPPORTED 80044407h
QNG stats not supported with this device.
QNG_E_DIAGX_UNSUPPORTED 80044408h
QNG diagnostics not supported with this device.
QNG_E_DEVICE_NOT_OPENED 8004440Ah
QNG device not found or already in use.
S_OK 00000000h
No error occurred.
C++ Example
// #import directive using full path to "QWQNG.dll"
#import "QWQNG.dll" no_namespace named_guids
int main() {
CoInitialize(NULL);
IQNGPtr qng = 0;
qng.CreateInstance(CLSID_QNG);
try {
// this will force a QNG_E_IO_ARRAY_OVERSIZED exception
qng->RandBytes[8193];
}
catch(_com_error& e) {
// Get exception description as a char*
_bstr_t bDsc = e.Description();
char* sDsc = (char*)bDsc;
printf("Error %X - %s\n\n", e.Error(), sDsc);
qng->Reset(); // attempting a reset to clear exception
}
return 0;
}
C# Example
// requires reference to "ComScire QNG Control Library 3.6"
using System;
using System.Runtime.InteropServices;
class Program {
static void Main(string[] args) {
QWQNG.QNG qng = new QWQNG.QNG();
try {
// this will force a QNG_E_IO_ARRAY_OVERSIZED exception
qng.get_RandBytes(8193);
}
catch (COMException exception) {
Console.WriteLine(exception.Message);
qng.Reset(); // attempting a reset to clear exception
}
}
}
Python Example
# requires PyWin32 extensions
import win32com.client
import pythoncom
qng = win32com.client.Dispatch("QWQNG.QNG")
try:
# this will force a QNG_E_IO_ARRAY_OVERSIZED exception
qng.RandBytes(8193)
except pythoncom.com_error, exception:
print exception
qng.Reset() # attempting a reset to clear exception
Select Algorithms
Random Range
Remarks
This algorithm uniformly selects a single number from a range of integers. It is equivalent to drawing a single number out of a bin that contains each number in the range from min-value to max-value. The maximum range length for this algorithm is 2^32, since 32 bit integers are assumed for randomizing. Note that exception and boundary conditions are not handled in the example code and should be added to production code.
Pseudo Code
(1) min_bound = least integer in number range
(2) max_bound = greatest integer in number range
(3) interval_len = max_bound - min_bound + 1
(4) int32_bound = 2^32 - (2^32 MODULO interval_len)
(5) rand32 = new random 32 bit unsigned integer
(6) IF rand32 > int32_bound THEN GOTO step 5
(7) return_val = min_bound + (rand32 MODULO interval_len)
Python Example
def random_range(min_bound, max_bound):
interval_len = max_bound - min_bound + 1
int32_bound = 2^32 - (2^32 % interval_len)
rand32 = qng.RandInt32
while rand32 > int32_bound:
rand32 = qng.RandInt32
return min_bound + (rand32 % interval_len)
Random Sample
Remarks
This algorithm uniformly draws n number of elements out of a given set of elements. It is equivalent to randomly selecting and removing items from a fixed set bin one by one.
Pseudo Code
(1) input_set = input set
(2) sample_count = desired sample set size
(3) element_index = CALL Random Range algorithm
WITH min_bound = 0 AND max_bound = sample set size - 1
(4) ADD input_set[element_index] TO sample_set
(6) REMOVE input_set[element_index] FROM input_set
(7) IF sample_set CONTAINS sample_count elements THEN
RETURN sample_set
ELSE
GOTO Step (3) WITH reduced input_set
Python Example
def random_sample(input_set, sample_count):
sample_set = []
while (len(sample_set) != sample_count):
element_index = random_range(0, len(input_set)-1)
sample_set.append(input_set[element_index])
input_set.pop(element_index)
return sample_set