Exemple #1
0
 /// <summary>
 ///	Makes sure that the stamp format is either 0 or 1, just in case we
 /// start to support say validating another stamp format but not
 /// producing it in the same ship.
 /// </summary>
 /// <param name="format">A StampFormat instance.</param>
 private void ValidateStampFormat(StampFormat format)
 {
     if ((format != StampFormat.Version0) && (format != StampFormat.Version1))
     {
         throw new NotSupportedException("Only version 0 and version 1 stamps are supported.");
     }
 }
Exemple #2
0
 public void GenerateAFormatVersionZeroStampWithADenominationOfSeventeenAndEnsureItValidatesUsingTheHashcashReferenceImplementation()
 {
     Given("a resource of '*****@*****.**'", x => Resource = "foo123456789")
     .And("an instance of the Minter class", x => Minter = new Minter())
     .And("a denomination of sixteen", x => Denomination = 17)
     .And("a stamp format version of 1", x => Format     = StampFormat.Version0)
     .When("the Mint method is called", x => Stamp       = Minter.Mint(Resource, Denomination, Format))
     .Then("it should generate a valid stamp", x => IsValidStamp(Denomination, Resource, Stamp, 0));
 }
Exemple #3
0
        private static void Main(string[] args)
        {
            string      resource     = args[0];
            int         denomination = int.Parse(args[1]);
            StampFormat format       = (StampFormat)Enum.Parse(typeof(StampFormat), $"Version{args[2]}");

            Minter minter = new Minter();
            string stamp  = minter.Mint(resource, denomination, DateTimeOffset.UtcNow, format);

            Console.WriteLine(stamp);

            Console.WriteLine("Press a key to exit...");
            Console.ReadKey();
        }
Exemple #4
0
        /// <summary>
        /// Mints a stamp given the input parameters.
        /// </summary>
        /// <param name="resource">The resource that the stamp is to be minted for.</param>
        /// <param name="requiredDenomination">The required denomination of the stamp.</param>
        /// <param name="date">The date that the stamp is to be minted for.</param>
        /// <param name="format">The format of the stamp to be produced.</param>
        /// <returns>A string representation of the hashcash stamp.</returns>
        public string Mint(string resource, int requiredDenomination, DateTime date, StampFormat format)
        {
            this.ValidateResource(resource);
            this.ValidateRequiredDenomination(requiredDenomination);
            this.ValidateStampFormat(format);

            int prefixLength;

            byte[] blankStamp     = this.CreateBlankStamp(resource, requiredDenomination, date, format, out prefixLength);
            byte[] collisionStamp = this.ComputePartialCollisionStamp(blankStamp, requiredDenomination, format, prefixLength);

            string stamp = Encoding.ASCII.GetString(collisionStamp);

            return(stamp);
        }
Exemple #5
0
        public static int Main(string[] args)
        {
            int returnCode = 0;

            try
            {
                string      resource     = args[0];
                int         denomination = int.Parse(args[1]);
                StampFormat format       = (StampFormat)Enum.Parse(typeof(StampFormat), string.Format("Version{0}", args[2]));

                NHashcash.Minter minter = new NHashcash.Minter();
                string           stamp  = minter.Mint(resource, denomination, DateTime.Now, format);
                Console.WriteLine(stamp);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                returnCode = 1;
            }

            return(returnCode);
        }
Exemple #6
0
 /// <summary>
 /// Mints a stamp given the input parameters.
 /// </summary>
 /// <param name="resource">The resource that the stamp is to be minted for.</param>
 /// <param name="requiredDenomination">The required denomination of the stamp.</param>
 /// <param name="format">The format of the stamp to be produced.</param>
 /// <returns>A string representation of the hashcash stamp.</returns>
 public string Mint(string resource, int requiredDenomination, StampFormat format)
 {
     return(Mint(resource, requiredDenomination, DateTimeOffset.UtcNow, format));
 }
Exemple #7
0
 /// <summary>
 /// Mints a stamp given the input parameters.
 /// </summary>
 /// <param name="resource">The resource that the stamp is to be minted for.</param>
 /// <param name="date">The date that the stamp is to be minted for.</param>
 /// <param name="format">The format of the stamp to be produced.</param>
 /// <returns>A string representation of the hashcash stamp.</returns>
 public string Mint(string resource, DateTimeOffset date, StampFormat format)
 {
     return(Mint(resource, DefaultDenomination, date, format));
 }
Exemple #8
0
        /// <summary>
        /// Generates the stamp prefix bytes from the inputs.
        /// </summary>
        /// <param name="resource">The resource that the stamp is being produced for.</param>
        /// <param name="requiredDenomination">The required denomination of the stamp.</param>
        /// <param name="date">The date that the stamp is to be minted for.</param>
        /// <param name="format">The format of the stamp to be produced.</param>
        /// <returns>A byte array containing the stamp prefix.</returns>
        private byte[] GenerateStampPrefixBytes(string resource, int requiredDenomination, DateTimeOffset date, StampFormat format)
        {
            string stampPrefix = null;
            string stampDate   = date.ToString("yymmdd");

            switch (format)
            {
            case StampFormat.Version0:
                stampPrefix = $"0:{stampDate}:{resource}:";
                break;

            case StampFormat.Version1:
                stampPrefix = $"1:{requiredDenomination}:{stampDate}:{resource}::";
                break;
            }

            byte[] stampPrefixBytes = Encoding.ASCII.GetBytes(stampPrefix);

            return(stampPrefixBytes);
        }
Exemple #9
0
        /// <summary>
        /// Creates a byte array containing the stamp prefix and is padded out to the required length.
        /// </summary>
        /// <param name="resource">The resource that the stamp is being produced for.</param>
        /// <param name="requiredDenomination">The required denomination of the stamp.</param>
        /// <param name="date">The date that the stamp is to be minted for.</param>
        /// <param name="format">The format of the stamp.</param>
        /// <param name="prefixLength">The length of the stamp prefix after all its elements have been pieced together.</param>
        /// <returns>A byte array containing the stamp prefix and the required amount of padding.</returns>
        private byte[] CreateBlankStamp(string resource, int requiredDenomination, DateTimeOffset date, StampFormat format, out int prefixLength)
        {
            byte[] stampPrefixBytes = GenerateStampPrefixBytes(resource, requiredDenomination, date, format);
            prefixLength = stampPrefixBytes.Length;

            int paddedLength = CalculatePaddedLength(prefixLength);

            byte[] blankStamp = new byte[paddedLength];
            Array.Copy(stampPrefixBytes, blankStamp, stampPrefixBytes.Length);

            return(blankStamp);
        }
Exemple #10
0
        /// <summary>
        /// This is the main part of the algorithm. It takes a blank template stamp and randomly replaces the
        /// characters after the prefix until
        /// </summary>
        /// <param name="blankStamp"></param>
        /// <param name="requiredDenomination"></param>
        /// <param name="format"></param>
        /// <param name="prefixLength"></param>
        /// <returns></returns>
        private byte[] ComputePartialCollisionStamp(byte[] blankStamp, int requiredDenomination, StampFormat format, int prefixLength)
        {
            byte[] collisionStamp = blankStamp;

            int randomRangeLowerLimit = prefixLength;
            int randomRangeUpperLimit = collisionStamp.Length;

            SHA1Managed provider = new SHA1Managed();

            int hashCounter = 0;

            bool collisionFound = false;

            while (collisionFound == false)
            {
                if (format == StampFormat.Version1)
                {
                    byte[] hashCounterBytes = CreateCounterBasedOnCharacterSet(hashCounter);
                    Array.Copy(
                        hashCounterBytes,
                        0,
                        collisionStamp,
                        collisionStamp.Length - hashCounterBytes.Length,
                        hashCounterBytes.Length
                        );
                    randomRangeUpperLimit = collisionStamp.Length - hashCounterBytes.Length - 1;
                    collisionStamp[randomRangeUpperLimit] = 58;
                }

                int  bytePosition  = _numberGenerator.Next(randomRangeLowerLimit, randomRangeUpperLimit);
                byte characterByte = GetRandomCharacter();
                collisionStamp[bytePosition] = characterByte;

                byte[] collisionStampHash = provider.ComputeHash(collisionStamp);
                collisionFound = IsCollisionOfRequiredDenomination(collisionStampHash, requiredDenomination);

                hashCounter++;
            }

            return(collisionStamp);
        }
Exemple #11
0
 /// <summary>
 /// Mints a stamp given the input parameters.
 /// </summary>
 /// <param name="resource">The resource that the stamp is to be minted for.</param>
 /// <param name="requiredDenomination">The required denomination of the stamp.</param>
 /// <param name="format">The format of the stamp to be produced.</param>
 /// <returns>A string representation of the hashcash stamp.</returns>
 public string Mint(string resource, int requiredDenomination, StampFormat format)
 {
     return(this.Mint(resource, requiredDenomination, DateTime.Now, format));
 }
Exemple #12
0
 /// <summary>
 /// Mints a stamp given the input parameters.
 /// </summary>
 /// <param name="resource">The resource that the stamp is to be minted for.</param>
 /// <param name="date">The date that the stamp is to be minted for.</param>
 /// <param name="format">The format of the stamp to be produced.</param>
 /// <returns>A string representation of the hashcash stamp.</returns>
 public string Mint(string resource, DateTime date, StampFormat format)
 {
     return(this.Mint(resource, this.DefaultDenomination, date, format));
 }
Exemple #13
0
        /// <summary>
        /// Generates the stamp prefix bytes from the inputs.
        /// </summary>
        /// <param name="resource">The resource that the stamp is being produced for.</param>
        /// <param name="requiredDenomination">The required denomination of the stamp.</param>
        /// <param name="date">The date that the stamp is to be minted for.</param>
        /// <param name="format">The format of the stamp to be produced.</param>
        /// <returns>A byte array containing the stamp prefix.</returns>
        private byte[] GenerateStampPrefixBytes(string resource, int requiredDenomination, DateTime date, StampFormat format)
        {
            string stampPrefix = null;
            string stampDate   = date.ToString("yyMMdd");

            switch (format)
            {
            case StampFormat.Version0:
                stampPrefix = string.Format(
                    "0:{0}:{1}:",
                    stampDate,
                    resource
                    );
                break;

            case StampFormat.Version1:
                stampPrefix = string.Format(
                    "1:{0}:{1}:{2}::",
                    requiredDenomination,
                    stampDate,
                    resource
                    );
                break;
            }

            byte[] stampPrefixBytes = Encoding.ASCII.GetBytes(stampPrefix);

            return(stampPrefixBytes);
        }