|
![]() |
|
Registriert seit: 28. Feb 2016 Ort: Nordost Baden-Württemberg 3.099 Beiträge Delphi 12 Athens |
#1
Ich sehe wenig Sinn darin, die Flexibilität zu beschränken, wenn es auch anders geht.
Ja, GCM wird hautsächlich auf AES angewendet. Das kann man ja so dokumentieren. Aber wenn ein neuer Standard mal kommt der auch 128 Bit Blöcke nuntzt und GCM für den auch einigermaßen üblich ist müsste man ja wieder ran. Lieber die Zeit dafür nutzen und die problematische Umsetzung für Streams ändern. Das muss man so wie es aussieht für die vor kurzem eingeführten Paddings wie Pkcs#7 sowieso auch tun. Und dann vermutlich zuerst für diese und danach für GCM, oder arbeitet das auf den ungepaddeten Daten? Mir schwebt eine überladene Done Variante mit Parametern vor (vermutlich der Input und der Output Stream). Wenn man will kann man kann man nih ein Flag einbauen, welches beim Aufruf von Encode/DecodeStream auf True gesetzt werden und würde, wenn das gesetzt ist, im normalen Done eine Exception werfen. Damit würde man die Entwickler sicher erziehen (bis auf die, die ihren Code nicht testen)... ![]() * Ich denke multiple Calls zu EncodeBytes / EncodeStream sollten evt. doch zugelassen werden -
alle anderen Cipher, die ja nicht voneinander abhängig sind funktionieren ja so auch... Es bräuchte hier nur etwas mehr "housekeeping" (status, counter, schon initialiert usw.) gemacht. Ein Call von "Done" würde dann natürlich das Ganze abschließen und das Finale Tag berechnen.... See stream functionality does need signal to end as it can and most likely used as chunk or repeated calls, "Done" will signal the sealing of the GCM tag calculation by multiply the last chained result with the first block (the one with counter=0), but enforcing requirement will break the one hit EncodeBytes/DecodeBytes, i saw these being used in many places in one line of code, enforcing "Done" with them is wrong, yet i support the functionality itself, but it must be different, may be different pair of functions, like EncodeChunk that accept TBytes or ... But in general moving GCM into own class is not bad idea, just costly in implementation, and will make the code cleaner as one line operation like EncodeBytes can use that GCM and call done internally, yet it might be not small refactor.[/QUOTE] GCM ist bereits eine separate Klasse und Unit, weil das komplizierter/aufwändiger als die anderen Blockmodi ist. Das wird dann halt in DECCipherModes aufgerufen. Wie oben geschrieben: meine aktuelle Idee ist es, das Ende der Streamoperation per überladener Done Methode zu signalisieren.
Grüße
TurboMagic |
![]() |
Registriert seit: 13. Dez 2007 Ort: Bruck an der Mur 77 Beiträge |
#2
Ich sehe wenig Sinn darin, die Flexibilität zu beschränken, wenn es auch anders geht.
Ja, GCM wird hautsächlich auf AES angewendet. Das kann man ja so dokumentieren. Aber wenn ein neuer Standard mal kommt der auch 128 Bit Blöcke nuntzt und GCM für den auch einigermaßen üblich ist müsste man ja wieder ran. Lieber die Zeit dafür nutzen und die problematische Umsetzung für Streams ändern. Das muss man so wie es aussieht für die vor kurzem eingeführten Paddings wie Pkcs#7 sowieso auch tun. Und dann vermutlich zuerst für diese und danach für GCM, oder arbeitet das auf den ungepaddeten Daten? Mir schwebt eine überladene Done Variante mit Parametern vor (vermutlich der Input und der Output Stream). Wenn man will kann man kann man nih ein Flag einbauen, welches beim Aufruf von Encode/DecodeStream auf True gesetzt werden und würde, wenn das gesetzt ist, im normalen Done eine Exception werfen. Damit würde man die Entwickler sicher erziehen (bis auf die, die ihren Code nicht testen)... ![]() letzten noch zwischegespeicherten Daten zurück liefern.... Ich bin nicht unbedingt ein Fan von super algemeinen Methoden, die niemand benutzt und oft die Sache nur verkompliziert und fehleranfällig macht... Gibt es ein RFC dass GCM nicht in Verbindung mit AES enthält? Selbes gilt für Poly1305 - Es wird praktisch nicht mit AES verwendet! ![]() |
![]() |
Registriert seit: 3. Sep 2023 477 Beiträge |
#3
Well here ChaCha implementation to save you both some time, it is correct and working but i mixed the following code form two different project in haste, also while i tested it for many edge case, it is far from optimized for speed
Delphi-Quellcode:
unit ChaCha;
interface uses SysUtils; type TChaChaRounds = (cr8, cr12, cr20); TChaChaKey = array[0..31] of Byte; // 256-bit key TChaChaNonce = array[0..11] of Byte; // 96-bit nonce TChaChaBlock = array[0..63] of Byte; // 512-bit block TChaCha = class private FState: array[0..15] of Cardinal; // Internal state procedure QuarterRound(var a, b, c, d: Cardinal); procedure InnerBlock; procedure SetupState(const Key: TChaChaKey; const Nonce: TChaChaNonce; Counter: Cardinal); {$IFDEF CHACHA_DEBUG} procedure DebugState(const DbgStr: string); {$ENDIF} public procedure Encrypt(const Key: TChaChaKey; const Nonce: TChaChaNonce; Counter: Cardinal; Rounds: TChaChaRounds; const Input: TBytes; var Output: TBytes); class procedure SelfTest; end; implementation const SIGMA: array[0..3] of Cardinal = ($61707865, $3320646e, $79622d32, $6b206574); // "expand 32-byte k" { TChaCha } {$IFDEF CHACHA_DEBUG} procedure TChaCha.DebugState(const DbgStr: string); var I: Integer; begin WriteLn(DbgStr); for I := 0 to 15 do begin Write(Format('%08x ', [FState[I]])); if (I + 1) mod 4 = 0 then WriteLn; end; WriteLn; end; {$ENDIF} procedure TChaCha.QuarterRound(var a, b, c, d: Cardinal); begin {$IFOPT R+}{$DEFINE RND_HasRangeChecks}{$ENDIF} {$IFOPT Q+}{$DEFINE RND_HasOverflowChecks}{$ENDIF} {$RANGECHECKS OFF} {$OVERFLOWCHECKS OFF} a := a + b; d := d xor a; d := (d shl 16) or (d shr 16); c := c + d; b := b xor c; b := (b shl 12) or (b shr 20); a := a + b; d := d xor a; d := (d shl 8) or (d shr 24); c := c + d; b := b xor c; b := (b shl 7) or (b shr 25); {$IFDEF RND_HasRangeChecks}{$RANGECHECKS ON}{$ENDIF} {$IFDEF RND_HasOverflowChecks}{$OVERFLOWCHECKS ON}{$ENDIF} end; procedure TChaCha.InnerBlock; var x: array[0..15] of Cardinal; begin Move(FState, x, SizeOf(x)); QuarterRound(x[0], x[4], x[8], x[12]); QuarterRound(x[1], x[5], x[9], x[13]); QuarterRound(x[2], x[6], x[10], x[14]); QuarterRound(x[3], x[7], x[11], x[15]); QuarterRound(x[0], x[5], x[10], x[15]); QuarterRound(x[1], x[6], x[11], x[12]); QuarterRound(x[2], x[7], x[8], x[13]); QuarterRound(x[3], x[4], x[9], x[14]); Move(x, FState, SizeOf(FState)); end; procedure TChaCha.SetupState(const Key: TChaChaKey; const Nonce: TChaChaNonce; Counter: Cardinal); begin FState[0] := SIGMA[0]; FState[1] := SIGMA[1]; FState[2] := SIGMA[2]; FState[3] := SIGMA[3]; Move(Key[0], FState[4], 32); FState[12] := Counter; Move(Nonce[0], FState[13], 12); end; procedure ChaChaBlockSIMD(State: Pointer; Rounds: Integer); {$IF Defined(CPUX86) or Defined(CPUX64)} asm // Save state movdqu xmm0, dqword [State+00] // Use movdqa for aligned access or switch to movdqu for unaligned movdqu xmm1, dqword [State+16] movdqu xmm2, dqword [State+32] movdqu xmm3, dqword [State+48] // Main loop @ROUND: // Column round paddd xmm0, xmm1 pxor xmm3, xmm0 pshuflw xmm3, xmm3, 0B1h pshufhw xmm3, xmm3, 0B1h paddd xmm2, xmm3 pxor xmm1, xmm2 movdqa xmm4, xmm1 pslld xmm1, 12 psrld xmm4, 20 por xmm1, xmm4 paddd xmm0, xmm1 pxor xmm3, xmm0 movdqa xmm4, xmm3 pslld xmm3, 8 psrld xmm4, 24 por xmm3, xmm4 paddd xmm2, xmm3 pxor xmm1, xmm2 movdqa xmm4, xmm1 pslld xmm1, 7 psrld xmm4, 25 por xmm1, xmm4 // Shuffle for diagonal pshufd xmm1, xmm1, 39h pshufd xmm2, xmm2, 4Eh pshufd xmm3, xmm3, 93h // Diagonal round paddd xmm0, xmm1 pxor xmm3, xmm0 pshuflw xmm3, xmm3, 0B1h pshufhw xmm3, xmm3, 0B1h paddd xmm2, xmm3 pxor xmm1, xmm2 movdqa xmm4, xmm1 pslld xmm1, 12 psrld xmm4, 20 por xmm1, xmm4 paddd xmm0, xmm1 pxor xmm3, xmm0 movdqa xmm4, xmm3 pslld xmm3, 8 psrld xmm4, 24 por xmm3, xmm4 paddd xmm2, xmm3 pxor xmm1, xmm2 movdqa xmm4, xmm1 pslld xmm1, 7 psrld xmm4, 25 por xmm1, xmm4 // Shuffle back pshufd xmm1, xmm1, 93h pshufd xmm2, xmm2, 4Eh pshufd xmm3, xmm3, 39h dec Rounds jnz @ROUND {// Add original state paddd xmm0, dqword [State+00] // Use dqword for aligned access, paddd must have memory aligned ! paddd xmm1, dqword [State+16] paddd xmm2, dqword [State+32] paddd xmm3, dqword [State+48] } movdqu xmm4, dqword [State+00] // unaligned memory state addition paddd xmm0, xmm4 movdqu xmm4, dqword [State+16] paddd xmm1, xmm4 movdqu xmm4, dqword [State+32] paddd xmm2, xmm4 movdqu xmm4, dqword [State+48] paddd xmm3, xmm4 // Store result movdqu dqword [State+00], xmm0 // Use movdqa for aligned store or switch to movdqu for unaligned movdqu dqword [State+16], xmm1 movdqu dqword [State+32], xmm2 movdqu dqword [State+48], xmm3 end; {$ELSE} begin RaiseError(ERR_SIMD_NOT_SUPPORTED); end; {$ENDIF} const SIMDEnabled = true; procedure TChaCha.Encrypt(const Key: TChaChaKey; const Nonce: TChaChaNonce; Counter: Cardinal; Rounds: TChaChaRounds; const Input: TBytes; var Output: TBytes); var I, J, RoundCount: Integer; OrigState: array[0..15] of Cardinal; Keystream: TChaChaBlock; PKeystream: PByte; begin SetLength(Output, Length(Input)); if Length(Input) = 0 then Exit; case Rounds of cr8: RoundCount := 8; cr12: RoundCount := 12; cr20: RoundCount := 20; else RoundCount := 20; end; for I := 0 to (Length(Input) - 1) div 64 do begin SetupState(Key, Nonce, Counter + Cardinal(I)); Move(FState, OrigState, SizeOf(FState)); {$IFDEF CHACHA_DEBUG} DebugState('Before InnerBlock:'); {$ENDIF} if SIMDEnabled then begin ChaChaBlockSIMD(@FState[0],RoundCount shr 1); end else begin for J := 1 to RoundCount shr 1 do begin InnerBlock; {$IFDEF CHACHA_DEBUG} DebugState(Format('After InnerBlock %d:', [J])); {$ENDIF} end; for J := 0 to 15 do FState[J] := Cardinal(UInt64(FState[J]) + UInt64(OrigState[J])); end; {$IFDEF CHACHA_DEBUG} DebugState('After adding OrigState:'); {$ENDIF} Move(FState, Keystream, SizeOf(Keystream)); {$IFDEF CHACHA_DEBUG} Write('Keystream: '); for J := 0 to 63 do Write(Format('%02x ', [Keystream[J]])); WriteLn; {$ENDIF} PKeystream := @Keystream; for J := 0 to 63 do begin if (I * 64 + J) >= Length(Input) then Break; Output[I * 64 + J] := Input[I * 64 + J] xor PKeystream^; Inc(PKeystream); end; end; // erase memory FillChar(FState, SizeOf(FState), 0); FillChar(Keystream, SizeOf(Keystream), 0); FillChar(OrigState, SizeOf(OrigState), 0); end; class procedure TChaCha.SelfTest; const KEY1: TChaChaKey = ( $00, $01, $02, $03, $04, $05, $06, $07, $08, $09, $0a, $0b, $0c, $0d, $0e, $0f, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $1a, $1b, $1c, $1d, $1e, $1f ); NONCE1: TChaChaNonce = ( $00, $00, $00, $00, $00, $00, $00, $4a, $00, $00, $00, $00 ); PLAINTEXT1: array[0..113] of Byte = ( $4c, $61, $64, $69, $65, $73, $20, $61, $6e, $64, $20, $47, $65, $6e, $74, $6c, $65, $6d, $65, $6e, $20, $6f, $66, $20, $74, $68, $65, $20, $63, $6c, $61, $73, $73, $20, $6f, $66, $20, $27, $39, $39, $3a, $20, $49, $66, $20, $49, $20, $63, $6f, $75, $6c, $64, $20, $6f, $66, $66, $65, $72, $20, $79, $6f, $75, $20, $6f, $6e, $6c, $79, $20, $6f, $6e, $65, $20, $74, $69, $70, $20, $66, $6f, $72, $20, $74, $68, $65, $20, $66, $75, $74, $75, $72, $65, $2c, $20, $73, $75, $6e, $73, $63, $72, $65, $65, $6e, $20, $77, $6f, $75, $6c, $64, $20, $62, $65, $20, $69, $74, $2e ); EXPECTED_CIPHERTEXT1: array[0..113] of Byte = ( $6e, $2e, $35, $9a, $25, $68, $f9, $80, $41, $ba, $07, $28, $dd, $0d, $69, $81, $e9, $7e, $7a, $ec, $1d, $43, $60, $c2, $0a, $27, $af, $cc, $fd, $9f, $ae, $0b, $f9, $1b, $65, $c5, $52, $47, $33, $ab, $8f, $59, $3d, $ab, $cd, $62, $b3, $57, $16, $39, $d6, $24, $e6, $51, $52, $ab, $8f, $53, $0c, $35, $9f, $08, $61, $d8, $07, $ca, $0d, $bf, $50, $0d, $6a, $61, $56, $a3, $8e, $08, $8a, $22, $b6, $5e, $52, $bc, $51, $4d, $16, $cc, $f8, $06, $81, $8c, $e9, $1a, $b7, $79, $37, $36, $5a, $f9, $0b, $bf, $74, $a3, $5b, $e6, $b4, $0b, $8e, $ed, $f2, $78, $5e, $42, $87, $4d ); KEY2: TChaChaKey = ( $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $01 ); NONCE2: TChaChaNonce = ( $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $02 ); PLAINTEXT2: array[0..374] of Byte = ( $41, $6e, $79, $20, $73, $75, $62, $6d, $69, $73, $73, $69, $6f, $6e, $20, $74, $6f, $20, $74, $68, $65, $20, $49, $45, $54, $46, $20, $69, $6e, $74, $65, $6e, $64, $65, $64, $20, $62, $79, $20, $74, $68, $65, $20, $43, $6f, $6e, $74, $72, $69, $62, $75, $74, $6f, $72, $20, $66, $6f, $72, $20, $70, $75, $62, $6c, $69, $63, $61, $74, $69, $6f, $6e, $20, $61, $73, $20, $61, $6c, $6c, $20, $6f, $72, $20, $70, $61, $72, $74, $20, $6f, $66, $20, $61, $6e, $20, $49, $45, $54, $46, $20, $49, $6e, $74, $65, $72, $6e, $65, $74, $2d, $44, $72, $61, $66, $74, $20, $6f, $72, $20, $52, $46, $43, $20, $61, $6e, $64, $20, $61, $6e, $79, $20, $73, $74, $61, $74, $65, $6d, $65, $6e, $74, $20, $6d, $61, $64, $65, $20, $77, $69, $74, $68, $69, $6e, $20, $74, $68, $65, $20, $63, $6f, $6e, $74, $65, $78, $74, $20, $6f, $66, $20, $61, $6e, $20, $49, $45, $54, $46, $20, $61, $63, $74, $69, $76, $69, $74, $79, $20, $69, $73, $20, $63, $6f, $6e, $73, $69, $64, $65, $72, $65, $64, $20, $61, $6e, $20, $22, $49, $45, $54, $46, $20, $43, $6f, $6e, $74, $72, $69, $62, $75, $74, $69, $6f, $6e, $22, $2e, $20, $53, $75, $63, $68, $20, $73, $74, $61, $74, $65, $6d, $65, $6e, $74, $73, $20, $69, $6e, $63, $6c, $75, $64, $65, $20, $6f, $72, $61, $6c, $20, $73, $74, $61, $74, $65, $6d, $65, $6e, $74, $73, $20, $69, $6e, $20, $49, $45, $54, $46, $20, $73, $65, $73, $73, $69, $6f, $6e, $73, $2c, $20, $61, $73, $20, $77, $65, $6c, $6c, $20, $61, $73, $20, $77, $72, $69, $74, $74, $65, $6e, $20, $61, $6e, $64, $20, $65, $6c, $65, $63, $74, $72, $6f, $6e, $69, $63, $20, $63, $6f, $6d, $6d, $75, $6e, $69, $63, $61, $74, $69, $6f, $6e, $73, $20, $6d, $61, $64, $65, $20, $61, $74, $20, $61, $6e, $79, $20, $74, $69, $6d, $65, $20, $6f, $72, $20, $70, $6c, $61, $63, $65, $2c, $20, $77, $68, $69, $63, $68, $20, $61, $72, $65, $20, $61, $64, $64, $72, $65, $73, $73, $65, $64, $20, $74, $6f ); EXPECTED_CIPHERTEXT2: array[0..374] of Byte = ( $a3, $fb, $f0, $7d, $f3, $fa, $2f, $de, $4f, $37, $6c, $a2, $3e, $82, $73, $70, $41, $60, $5d, $9f, $4f, $4f, $57, $bd, $8c, $ff, $2c, $1d, $4b, $79, $55, $ec, $2a, $97, $94, $8b, $d3, $72, $29, $15, $c8, $f3, $d3, $37, $f7, $d3, $70, $05, $0e, $9e, $96, $d6, $47, $b7, $c3, $9f, $56, $e0, $31, $ca, $5e, $b6, $25, $0d, $40, $42, $e0, $27, $85, $ec, $ec, $fa, $4b, $4b, $b5, $e8, $ea, $d0, $44, $0e, $20, $b6, $e8, $db, $09, $d8, $81, $a7, $c6, $13, $2f, $42, $0e, $52, $79, $50, $42, $bd, $fa, $77, $73, $d8, $a9, $05, $14, $47, $b3, $29, $1c, $e1, $41, $1c, $68, $04, $65, $55, $2a, $a6, $c4, $05, $b7, $76, $4d, $5e, $87, $be, $a8, $5a, $d0, $0f, $84, $49, $ed, $8f, $72, $d0, $d6, $62, $ab, $05, $26, $91, $ca, $66, $42, $4b, $c8, $6d, $2d, $f8, $0e, $a4, $1f, $43, $ab, $f9, $37, $d3, $25, $9d, $c4, $b2, $d0, $df, $b4, $8a, $6c, $91, $39, $dd, $d7, $f7, $69, $66, $e9, $28, $e6, $35, $55, $3b, $a7, $6c, $5c, $87, $9d, $7b, $35, $d4, $9e, $b2, $e6, $2b, $08, $71, $cd, $ac, $63, $89, $39, $e2, $5e, $8a, $1e, $0e, $f9, $d5, $28, $0f, $a8, $ca, $32, $8b, $35, $1c, $3c, $76, $59, $89, $cb, $cf, $3d, $aa, $8b, $6c, $cc, $3a, $af, $9f, $39, $79, $c9, $2b, $37, $20, $fc, $88, $dc, $95, $ed, $84, $a1, $be, $05, $9c, $64, $99, $b9, $fd, $a2, $36, $e7, $e8, $18, $b0, $4b, $0b, $c3, $9c, $1e, $87, $6b, $19, $3b, $fe, $55, $69, $75, $3f, $88, $12, $8c, $c0, $8a, $aa, $9b, $63, $d1, $a1, $6f, $80, $ef, $25, $54, $d7, $18, $9c, $41, $1f, $58, $69, $ca, $52, $c5, $b8, $3f, $a3, $6f, $f2, $16, $b9, $c1, $d3, $00, $62, $be, $bc, $fd, $2d, $c5, $bc, $e0, $91, $19, $34, $fd, $a7, $9a, $86, $f6, $e6, $98, $ce, $d7, $59, $c3, $ff, $9b, $64, $77, $33, $8f, $3d, $a4, $f9, $cd, $85, $14, $ea, $99, $82, $cc, $af, $b3, $41, $b2, $38, $4d, $d9, $02, $f3, $d1, $ab, $7a, $c6, $1d, $d2, $9c, $6f, $21, $ba, $5b, $86, $2f, $37, $30, $e3, $7c, $fd, $c4, $fd, $80, $6c, $22, $f2, $21 ); var ChaCha: TChaCha; Input, Output: TBytes; I: Integer; Pass: Boolean; begin ChaCha := TChaCha.Create; try SetLength(Input, Length(PLAINTEXT1)); Move(PLAINTEXT1, Input[0], Length(PLAINTEXT1)); ChaCha.Encrypt(KEY1, NONCE1, 1, cr20, Input, Output); Pass := True; if Length(Output) <> Length(EXPECTED_CIPHERTEXT1) then Pass := False else for I := 0 to Length(EXPECTED_CIPHERTEXT1) - 1 do if Output[I] <> EXPECTED_CIPHERTEXT1[I] then begin Pass := False; WriteLn(Format('Test Vector 1: Mismatch at byte %d: got %02x, expected %02x', [I, Output[I], EXPECTED_CIPHERTEXT1[I]])); Break; end; if not Pass then raise Exception.Create('ChaCha20 Test Vector 1 failed!'); SetLength(Input, Length(PLAINTEXT2)); Move(PLAINTEXT2, Input[0], Length(PLAINTEXT2)); ChaCha.Encrypt(KEY2, NONCE2, 1, cr20, Input, Output); Pass := True; if Length(Output) <> Length(EXPECTED_CIPHERTEXT2) then Pass := False else for I := 0 to Length(EXPECTED_CIPHERTEXT2) - 1 do if Output[I] <> EXPECTED_CIPHERTEXT2[I] then begin Pass := False; WriteLn(Format('Test Vector 2: Mismatch at byte %d: got %02x, expected %02x', [I, Output[I], EXPECTED_CIPHERTEXT2[I]])); Break; end; if not Pass then raise Exception.Create('ChaCha20 Test Vector 2 failed!'); SetLength(Input, Length(PLAINTEXT1)); Move(PLAINTEXT1, Input[0], Length(PLAINTEXT1)); ChaCha.Encrypt(KEY1, NONCE1, 1, cr8, Input, Output); ChaCha.Encrypt(KEY1, NONCE1, 1, cr12, Input, Output); WriteLn('ChaCha self-test passed successfully.'); finally ChaCha.Free; end; end; end.
Kas
|
![]() |
Registriert seit: 3. Sep 2023 477 Beiträge |
#4
Missed this part
Delphi-Quellcode:
class procedure TCSPRNG.DetectSIMDSupport;
{$IF Defined(CPUX86) or Defined(CPUX64)} asm {$IFDEF CPUX86} push ebx {$ENDIF} mov eax, 1 // CPUID leaf 1 cpuid test edx, 1 shl 26 // Check SSE2 bit (bit 26 in EDX) jz @NoSIMD mov byte ptr [FSIMDSupported], 1 jmp @Done @NoSIMD: mov byte ptr [FSIMDSupported], 0 @Done: { mov eax, 1 // CPUID leaf 1 (faster than mov eax,1 on some CPUs) cpuid xor al, al // AL = 0 (prepare for no SSE2) test edx, 1 shl 26 // Check SSE2 bit (bit 26 in EDX) setnz al // AL = 1 if supported, 0 otherwise mov [FSIMDSupported], al} {$IFDEF CPUX86} pop ebx {$ENDIF} end; {$ELSE} begin FSIMDSupported := False; // Non-x86 platforms use Pascal end; {$ENDIF}
Kas
|
![]() |
Registriert seit: 13. Dez 2007 Ort: Bruck an der Mur 77 Beiträge |
#5
Thanks for the implementation. (hey was that from the random generator mrmath
![]() ![]() I'm currently in the state of bringing the Poly1305 together with the chacha cipher.... And.. although it is stated that there are 20 rounds for the standard implementation the implementation does a "double round" which halfs the number (at least that is what I found when implementing the example from the RFC) Geändert von rabatscher (20. Mai 2025 um 10:30 Uhr) |
![]() |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |