public static KeyFinderResult <TKey> FindBest <TKey>( string ciphertext, IKeyedCipher <TKey> cipher, IKeySpaceSource <TKey> keySpace, ISpeculativePlaintextRanker speculativePlaintextRanker, Action <KeyFinderResult <TKey> > onBetterResultFound = null, CancellationToken cancellationToken = default(CancellationToken) ) { if (ciphertext == null) { throw new ArgumentNullException(nameof(ciphertext)); } if (cipher == null) { throw new ArgumentNullException(nameof(cipher)); } if (keySpace == null) { throw new ArgumentNullException(nameof(keySpace)); } if (speculativePlaintextRanker == null) { throw new ArgumentNullException(nameof(speculativePlaintextRanker)); } KeyFinderResult <TKey> best = null; object syncRoot = new object(); Parallel.ForEach( keySpace.GetKeys(), new ParallelOptions { CancellationToken = cancellationToken }, key => { string speculativePlaintext = cipher.Decrypt(ciphertext, key); double rank = speculativePlaintextRanker.Classify(speculativePlaintext); if (rank > (best?.Rank ?? 0)) { lock (syncRoot) { if (rank > (best?.Rank ?? 0)) { best = new KeyFinderResult <TKey>(key, speculativePlaintext, rank); onBetterResultFound?.Invoke(best); } } } } ); return(best); }
public static void FindAboveThreshold <TKey>( string ciphertext, IKeyedCipher <TKey> cipher, IKeySpaceSource <TKey> keySpace, ISpeculativePlaintextRanker speculativePlaintextRanker, Action <KeyFinderResult <TKey> > onImmediateResultFound, double threshold = 0.9, CancellationToken cancellationToken = default(CancellationToken) ) { if (ciphertext == null) { throw new ArgumentNullException(nameof(ciphertext)); } if (cipher == null) { throw new ArgumentNullException(nameof(cipher)); } if (keySpace == null) { throw new ArgumentNullException(nameof(keySpace)); } if (speculativePlaintextRanker == null) { throw new ArgumentNullException(nameof(speculativePlaintextRanker)); } if (threshold < 0 || threshold > 1) { throw new ArgumentOutOfRangeException(nameof(threshold)); } if (onImmediateResultFound == null) { throw new ArgumentNullException(nameof(onImmediateResultFound)); } Parallel.ForEach( keySpace.GetKeys(), new ParallelOptions { CancellationToken = cancellationToken }, key => { string speculativePlaintext = cipher.Decrypt(ciphertext, key); double rank = speculativePlaintextRanker.Classify(speculativePlaintext); if (rank >= threshold) { onImmediateResultFound(new KeyFinderResult <TKey>(key, speculativePlaintext, rank)); } } ); }
/// <summary> /// Pins a key to a <see cref="IKeyedCipher{TKey}"/> and converts it to a <see cref="ICipher"/>. /// </summary> /// <typeparam name="TKey">The type of the key of <paramref name="keyedCipher"/>.</typeparam> /// <param name="keyedCipher">The cipher to use.</param> /// <param name="key">The key to use.</param> /// <returns>A <see cref="ICipher"/> which operates with the provided fix key.</returns> public static ICipher Pin <TKey>(this IKeyedCipher <TKey> keyedCipher, TKey key) { if (keyedCipher == null) { throw new ArgumentNullException(nameof(keyedCipher)); } return(new PinnedKeyCipher <TKey>(keyedCipher, key)); }
public PinnedKeyCipher(IKeyedCipher <TKey> keyedCipher, TKey key) { if (keyedCipher == null) { throw new ArgumentNullException(nameof(keyedCipher)); } this.Cipher = keyedCipher; this.Key = key; }