CaptureInput() ist eine virtuelle Umschreibung für eine von dir zu programmierende Funktion die Input durch einen Menschen getätig capture'd also erfasst
Diese Funktion haste selber zu schreiben und ist garnicht so einfach wie man denkt. Das schwierigste Problem ist es dabei die Entropie = Verteilung der benutzten Daten zu berücksichtigen. Als Beispiel: die Aufgabe des Users ist es ein Lied in das Mikrophone zu pfeifen. Diesen Soundstream zeichnest du auf. Aber du darfst nun NICHT alle Bits eines Samples benutzten umd denn Human-Zufalls-Faktor zu extrahieren. Ein solches WAV besteht zB. aus 2x 16Bit Samples, eines pro Soundkanal bei Stereo. Von jedem dieser 2 16Bit Zahlen pro Sample darfst du NUR das unterste oder eventuell die zwei unteresten Bits extrahieren. Diese beiden Bits liegen im Wave, betrachtet als Soundkurve, um den "Nullpunkt" herum. Sie stellen also Rauschen dar das aber durch das Singen durch den Menschen eben unvorhersagbar und nicht reproduzierbar moduliert wurde, es ist aber eben Rauschen.
Nun, jetzt extrhierst du dies Daten aus dem Wave und diese landen im obigen Buffer[], der Hash darüber ist der Output des YARROW RNG.
Im Falle eines PCs sollte man den User wahllos auf dem Keyboard rumhacken lassen. Die untersten 1-2 Bits jedes
ASCII Zeichens landen im Buffer, komprimiert. Angenommen 1 Bit pro
ASCII Zeichen, somit ergeben 8
ASCII zeichen 1 Byte im Buffer. Oder du nimmst die Bewegungen der Maus. Auch hier werden nur die 1-2 Bits der X,Y Koordinate benutzt, oder eben die Parität der Koordinaten.
Ich hatte mal einen Code der über Mouse/Keyboard Hooks permanent im Hintergrund solche daten sammelte. ZUsätzlich wurde in der Registry ein 1024 Bytes großer Zufallsbuffer gespeichert. Beim Start der Anwendung werden die Hooks installiert, der interne Buffer mit dem in der Registry gespeicherten geladen, und dann jede Mousebewegung oder Tastendrücke in den Buffer per XOR eingearbeitet. Bei der Erzeugung eines Zufallswertes aus diesem Buffer wird nun dieser Buffer + einem Zähler (Counter) gehasht. Der Hash ist der Rückgabewert des Zufallsgenerators. Innerhalb der RNG Funktion wird natürlich der Counter jedesmal erhöht.
Param TProtection sollte nil sein.
Im Pseudocode sähe es so aus:
Delphi-Quellcode:
unit RNG;
interface
implementation
var
Buffer:
packed record
Pos: Integer;
Count: Integer;
Data:
array[0..1023]
of Byte;
end;
function MyMouseHook():
begin
Buffer.Data[Buffer.Pos] := Buffer.Data[Buffer.Pos]
shl (MousePos.X
and 1)
xor (MousePos.Y
and 1);
Buffer.Pos := (Buffer.Pos +1)
mod 1024;
Result := CallNextHookEx(...);
end;
fucntion MyKeyboardHook();
begin
Buffer.Data[Buffer.Pos] := Buffer.Data[Buffer.Pos]
shl (Key
and 1)
xor GetCurrentTick;
Buffer.Pos := (Buffer.Pos +1)
mod 1024;
end;
function PRNG: Integer;
type
PDigest = ^TDigest;
TDigest =
array[0..3]
of Cardinal;
// = 16 Bytes für MD5 Digest
var
Digest: PDigest;
begin
Inc(Buffer.Count);
with THash_MD5.Create
do
try
Init;
Calc(Buffer, SizeOf(Buffer));
Done;
// errechne Result
Digest := DigestKey;
Result := Digest[0]
xor Digest[1]
xor Digest[2]
xor Digest[3];
finally
Free;
end;
end;
initialization
Buffer.Pos := 0;
Buffer.Count := 0;
LoadBufferFromRegistry(Buffer.Data);
SetWindowsHookEx(WH_MOUSE, MyMouseHook, ..);
SetWidnowsHookEx(..., MyKeyboardHook, ...);
finalization
UnhookWindowsHook(..., ....);
SaveBufferToRegistry(Buffer.Data);
end.
Gruß Hagen