A class representing a proportion, or fraction, of numerator over denominator. This comes in handy when one might care about the actual magnitude of the numerator/denominator, which is list in a representation that divides the numerator by the denominator.
Exemple #1
0
 public static Proportion GetLargest(IEnumerable<Proportion> proportions)
 {
     Proportion max = new Proportion(0,ulong.MaxValue);
     foreach (Proportion p in proportions)
     {
         if (p.AsDouble > max.AsDouble)
             max = p;
     }
     return max;
 }
Exemple #2
0
        public static Proportion GetLargest(IEnumerable <Proportion> proportions)
        {
            Proportion max = new Proportion(0, ulong.MaxValue);

            foreach (Proportion p in proportions)
            {
                if (p.AsDouble > max.AsDouble)
                {
                    max = p;
                }
            }
            return(max);
        }
Exemple #3
0
 public FrequencyTrackerResult(MultiperiodFrequencyTracker <TKey> tracker, TKey key, IEnumerable <Proportion> proportions = null)
 {
     Tracker         = tracker;
     Key             = key;
     this.Proportion = new Proportion(0, ulong.MaxValue);
     if (proportions == null)
     {
         return;
     }
     foreach (Proportion proportion in proportions)
     {
         if (proportion.AsDouble > Proportion.AsDouble)
         {
             this.Proportion = proportion;
         }
     }
 }
        /// <summary>
        /// Estimate the popularity of a password among past incorrect passwords.
        /// This will also record the observation of the incorrect password if wasPasswordCorrect is false
        /// </summary>
        /// <param name="password">The password to estimate the popularity of.</param>
        /// <param name="wasPasswordCorrect">True if the passowrd provided was the correct password for this account</param>
        /// <param name="confidenceLevel">The confidence level required for the minimum threshold of popularity.</param>
        /// <param name="minDenominatorForPasswordPopularity">When there are few samples observations, use this minimum denomoninator
        /// to prevent something appearing popular just becausae we haven't seen much else yet.</param>
        /// <returns></returns>
        public Proportion GetPopularityOfPasswordAmongFailures(string password,
            bool wasPasswordCorrect, 
            double confidenceLevel = 0.001,
            ulong minDenominatorForPasswordPopularity = 10000)
        {
            int sketchBitsSet;

            if (!wasPasswordCorrect)
            {
                FailedPasswordsRecordedSoFar += 1d;
                sketchBitsSet = BinomialSketchOfFailedPasswords.Observe(password);
            }
            else
            {
                sketchBitsSet = BinomialSketchOfFailedPasswords.GetNumberOfIndexesSet(password);
            }
            Proportion highestPopularity = new Proportion(
                (ulong)BinomialSketchOfFailedPasswords.CountObservationsForGivenConfidence(sketchBitsSet, confidenceLevel),
                Math.Min((ulong) BinomialSketchOfFailedPasswords.NumberOfObservationsAccountingForAging, 
                                 minDenominatorForPasswordPopularity));
            
            string passwordHash = Convert.ToBase64String(SimplePasswordHash(password));

            // If we're already tracking this unsalted hash, or we've seen enough observations
            // in the binomial sketch that we're confident it's common enough to to be a very
            // good secret, we'll continue to track the unsalted hash
            if (PasswordFrequencyEstimatesForDifferentPeriods[0].Get(passwordHash).Numerator > 0 ||
                sketchBitsSet >= HeightOfLadderDeemedPopular)
                // FIXME BinomialSketchOfFailedPasswords.CountObservationsForGivenConfidence(sketchBitsSet, 0.000001d) >
                //_minCountRequiredToTrackPreciseOccurrences)
            {
                foreach (var passwordTrackerForThisPeriod in PasswordFrequencyEstimatesForDifferentPeriods)
                {
                    Proportion popularityForThisPeriod;
                    lock (passwordTrackerForThisPeriod)
                    {
                        popularityForThisPeriod = wasPasswordCorrect ? 
                            passwordTrackerForThisPeriod.Get(passwordHash) :
                            passwordTrackerForThisPeriod.Observe(passwordHash);
                    }
                    popularityForThisPeriod = popularityForThisPeriod.MinDenominator(minDenominatorForPasswordPopularity);
                    if (popularityForThisPeriod.AsDouble > highestPopularity.AsDouble)
                        highestPopularity = popularityForThisPeriod;
                }

                if (highestPopularity.Numerator >= _minCountRequiredToStorePlaintext &&
                    highestPopularity.AsDouble >= _minPercentRequiredToStorePlaintext)
                {
                    lock (MapOfHighlyPopularUnsaltedHashedPasswordsToPlaintextPasswords)
                    {
                        if (!MapOfHighlyPopularUnsaltedHashedPasswordsToPlaintextPasswords.ContainsKey(passwordHash))
                        {
                            MapOfHighlyPopularUnsaltedHashedPasswordsToPlaintextPasswords[passwordHash] = password;
                        }
                    }
                }
            }
            
            return highestPopularity;
        }
Exemple #5
0
 public Proportion Get(TKey key)
 {
     return(Proportion.GetLargest(
                PasswordFrequencyEstimatesForDifferentPeriods.Select(
                    (ft) => ft.Get(key))));
 }
Exemple #6
0
 public FrequencyTrackerResult(MultiperiodFrequencyTracker <TKey> tracker, TKey key, Proportion proportion)
 {
     Tracker         = tracker;
     Key             = key;
     this.Proportion = proportion;
 }