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<bytecount; i++) {
 		printf("%X ", (*randbyte)&0xff);
 		randbyte++;
 	}
 	SafeArrayUnaccessData(randvariant.parray);
 	printf ("\n");
 
 	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();
 		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<infoCount; i++) {
 		printf("%02i: %1.6f ", i, *runtimeInfo);
 		runtimeInfo++;
 	}
 	SafeArrayUnaccessData(randvariant.parray);
 	printf ("\n");
 
 	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();
 		float[] runtimeInfo = (float[])qng.RuntimeInfo;
 		for (int i=0; i<runtimeInfo.Length; i++)
 			Console.Write("{0}: {1} ", i, runtimeInfo[i]);
 		Console.WriteLine();
 	}
 }
				
			

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<byteCount; i++) {
 		printf("%02X ", *dxData);
 		dxData++;
 	}
 	SafeArrayUnaccessData(randvariant.parray);
 	printf ("\n");
 
 	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();
 
 		// 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