Exemple #1
0
        private (BitString output, string error) Prf(BitString secret, string label, BitString seed, int outputLength)
        {
            int lengthToGenerate = outputLength.CeilingDivide(_shaHmac.OutputLength * _md5Hmac.OutputLength) * (_shaHmac.OutputLength * _md5Hmac.OutputLength);

            if (secret.BitLength % 8 != 0)
            {
                return(null, "Invalid secret, must be whole byte");
            }

            var secretBytes   = secret.BitLength / 8;
            var halfSecretLen = secretBytes.CeilingDivide(2) * 8;

            var firstHalf  = secret.GetMostSignificantBits(halfSecretLen);
            var secondHalf = secret.GetLeastSignificantBits(halfSecretLen);

            var labelBytes = new BitString(Encoding.ASCII.GetBytes(label));
            var md5Out     = HmacPrf(_md5Hmac, firstHalf, labelBytes.ConcatenateBits(seed), lengthToGenerate);
            var shaOut     = HmacPrf(_shaHmac, secondHalf, labelBytes.ConcatenateBits(seed), lengthToGenerate);

            if (md5Out.BitLength != shaOut.BitLength)
            {
                return(null, "Invalid PRF output, lenghts must be equal");
            }

            var xorResult = md5Out.XOR(shaOut);

            return(xorResult.GetMostSignificantBits(outputLength), "");
        }
        public override SymmetricCipherResult Encrypt(BitString key, BitString plainText, bool wrapWithInverseCipher)
        {
            // 1. Let ICV2 = 0xA65959A6
            // 2. Let padlen = 8 * ceil(len(P)/64) - len(P)/8
            var padLen = 8 * (int)System.Math.Ceiling(plainText.BitLength / 64.0) - (plainText.BitLength / 8);

            // 3. Let PAD = 0^8*padlen
            var pad = BitString.Zeroes(8 * padLen);

            // 4. Let S = ICV2 || [len(P)/8] under 2^32 || P || PAD
            var S = new BitString(0);

            S = S.ConcatenateBits(Icv2);
            S = S.ConcatenateBits(BitString.To32BitString(plainText.BitLength / 8));
            S = S.ConcatenateBits(plainText);
            S = S.ConcatenateBits(pad);

            if (plainText.BitLength <= 64)
            {
                var aesResult = Cipher.ProcessPayload(new ModeBlockCipherParameters(BlockCipherDirections.Encrypt, key, S, wrapWithInverseCipher));
                return(aesResult.Success ? new SymmetricCipherResult(aesResult.Result) : new SymmetricCipherResult(aesResult.ErrorMessage));
            }
            else
            {
                var c = Wrap(key, S, wrapWithInverseCipher);
                return(new SymmetricCipherResult(c));
            }
        }
Exemple #3
0
        public KdfResult DeriveKey(BitString kI, BitString fixedData, int len, BitString iv = null, int breakLocation = 0)
        {
            // 1
            var n = len.CeilingDivide(Mac.OutputLength);

            // 2
            if (n > NumberTheory.Pow2(_counterLength) - 1)
            {
                return(new KdfResult("Counter length too long for operation"));
            }

            // 3
            var result = new BitString(0);

            // 4
            if (_counterLocation == CounterLocations.MiddleFixedData)
            {
                if (breakLocation < 1 || breakLocation > fixedData.BitLength - 1)
                {
                    return(new KdfResult("Invalid break location"));
                }
            }

            for (var i = 1; i <= n; i++)
            {
                var counterBits = BitString.To32BitString(i).GetLeastSignificantBits(_counterLength);
                var data        = new BitString(0);

                switch (_counterLocation)
                {
                case CounterLocations.BeforeFixedData:
                    data = data.ConcatenateBits(counterBits).ConcatenateBits(fixedData);
                    break;

                case CounterLocations.AfterFixedData:
                    data = data.ConcatenateBits(fixedData).ConcatenateBits(counterBits);
                    break;

                case CounterLocations.MiddleFixedData:
                    var firstPart  = fixedData.GetMostSignificantBits(breakLocation);
                    var secondPart = fixedData.MSBSubstring(breakLocation, fixedData.BitLength - breakLocation);
                    data = data.ConcatenateBits(firstPart).ConcatenateBits(counterBits).ConcatenateBits(secondPart);
                    break;

                default:
                    return(new KdfResult("Invalid Counter location"));
                }

                var kTemp = PseudoRandomFunction(kI, data);

                result = result.ConcatenateBits(kTemp);
            }

            // 5
            var kOut = result.GetMostSignificantBits(len);

            return(new KdfResult(kOut));
        }
Exemple #4
0
        // Computes Kc as described in rfc 8554
        public BitString Algorithm4b(BitString sig, BitString msg, BitString pubType, BitString I, BitString q)
        {
            // 1. If the signature is not at least four bytes long, return INVALID.
            if (sig.BitLength < 32)
            {
                return(null);
            }

            // 2. Parse sigtype, C, and y from the signature as follows:
            // a. sigtype = strTou32(first 4 bytes of signature)
            var sigType = sig.MSBSubstring(0, 32);

            // b. If sigtype is not equal to pubtype, return INVALID.
            if (!pubType.Equals(sigType))
            {
                return(null);
            }

            // c. Set n and p according to the pubtype and Table 1; if the signature is not exactly 4 + n * (p + 1)
            //    bytes long, return INVALID.
            var p = LmotsModeMapping.GetPFromCode(sigType);
            var n = LmotsModeMapping.GetNFromCode(sigType);

            if (sig.BitLength != (4 + (n * (p + 1))) * 8)
            {
                return(null);
            }

            // d. C = next n bytes of signature
            var C = sig.MSBSubstring(32, n * 8);

            // e. y[0] = next n bytes of signature
            //    y[1] = next n bytes of signature
            //    ...
            //    y[p - 1] = next n bytes of signature
            var y = sig.MSBSubstring((n * 8) + 32, p * n * 8);

            // 3. Compute the string Kc as described in rfc 8554
            var Q = _sha256.HashMessage(I
                                        .ConcatenateBits(q)
                                        .ConcatenateBits(D_MESG)
                                        .ConcatenateBits(C)
                                        .ConcatenateBits(msg)).Digest;
            var cksmQ  = CheckSum(Q);
            var QcksmQ = Q.ConcatenateBits(cksmQ);

            var z = LmsDllLoader.GenZ(_p, _n, _w, y.ToBytes(), QcksmQ.ToBytes(), I.ToBytes(), q.ToBytes());

            var concatenated = I.ConcatenateBits(q).ConcatenateBits(D_PBLC);

            concatenated = concatenated.ConcatenateBits(new BitString(z));

            var Kc = _sha256.HashMessage(concatenated).Digest;

            // 4. Return Kc.
            return(Kc);
        }
Exemple #5
0
        private BitString ConcatenatePieceOntoOtherInfo(string workingPiece)
        {
            BitString oi = new BitString(0);

            if (workingPiece.Equals("uPartyInfo", StringComparison.OrdinalIgnoreCase))
            {
                if (_thisPartyKeyAgreementRole == KeyAgreementRole.InitiatorPartyU)
                {
                    oi = oi.ConcatenateBits(BitString.GetAtLeastZeroLengthBitString(_thisPartyOtherInfo.PartyId));
                    oi = oi.ConcatenateBits(BitString.GetAtLeastZeroLengthBitString(_thisPartyOtherInfo.DkmNonce));
                }
                else
                {
                    oi = oi.ConcatenateBits(BitString.GetAtLeastZeroLengthBitString(_otherPartyOtherInfo.PartyId));
                    oi = oi.ConcatenateBits(BitString.GetAtLeastZeroLengthBitString(_otherPartyOtherInfo.DkmNonce));
                }

                return(oi);
            }

            if (workingPiece.Equals("vPartyInfo", StringComparison.OrdinalIgnoreCase))
            {
                if (_thisPartyKeyAgreementRole == KeyAgreementRole.ResponderPartyV)
                {
                    oi = oi.ConcatenateBits(BitString.GetAtLeastZeroLengthBitString(_thisPartyOtherInfo.PartyId));
                    oi = oi.ConcatenateBits(BitString.GetAtLeastZeroLengthBitString(_thisPartyOtherInfo.DkmNonce));
                }
                else
                {
                    oi = oi.ConcatenateBits(BitString.GetAtLeastZeroLengthBitString(_otherPartyOtherInfo.PartyId));
                    oi = oi.ConcatenateBits(BitString.GetAtLeastZeroLengthBitString(_otherPartyOtherInfo.DkmNonce));
                }

                return(oi);
            }

            if (workingPiece.Equals("counter", StringComparison.OrdinalIgnoreCase))
            {
                oi = oi.ConcatenateBits(new BitString(32).BitStringAddition(BitString.One()));

                return(oi);
            }

            if (workingPiece.StartsWith("literal[", StringComparison.OrdinalIgnoreCase))
            {
                // remove the "literal[]" to get just the hex value
                workingPiece = workingPiece.Replace("literal[", "").Replace("]", "");
                oi           = oi.ConcatenateBits(new BitString(workingPiece));

                return(oi);
            }

            throw new ArgumentException(nameof(workingPiece));
        }
Exemple #6
0
        // 30 1d
        //   30 13
        //     06 0b 2a 86 48 86 f7 0d 01 09 10 03 06          ; 3DES wrap OID
        //     04 04
        //       00 00 00 01                                   ; Counter
        //                                                     ; a0 omitted (not present), PartyAInfo (Optional)
        //   a2 06                                             ; a2 is flag for supplemental info (keyLength)
        //     04 04
        //       00 00 00 c0                                   ; KeyLen (192 bits in this example)

        // 30 61
        //   30 13
        //     06 0b 2a 86 48 86 f7 0d 01 09 10 03 06
        //     04 04
        //       00 00 00 01
        //   a0 42
        //     04 40 ff e9 be b1 2d 30 aa a6 a6 2d 7f 6e eb 1c f3 bb 43 d4 44 53 4d 61 b4 4f f5 d6 67 5b f5 11 dd b5 d8 4a 55 24 64 fa 40 f8 3e cd 07 29 9c 18 04 b9 37 6d 4a c0 90 12 aa 0b 7a 51 a4 ea 96 ab ae f6
        //   a2 06
        //     04 04
        //       00 00 00 c0

        // 30 1D
        //   30 13
        //     06 0B 2A 86 48 86 F7 0D 01 09 10 03 06
        //     04 04
        //       00 00 00 01
        //   A2 06
        //     04 04
        //       00 00 01 00

        private BitString DerEncode(DerAns942Parameters derParams, BitString counter)
        {
            // Octet type || 4 bytes || value
            var counterOctet = AnsDerEncodingHelper.EncodeOctet(counter);

            // Concatenate OID and Counter as a sequence
            var algorithmIdentifier = AnsDerEncodingHelper.EncodeSequence(derParams.Oid.ConcatenateBits(counterOctet));

            // All optional information
            // a0-a3 || len || value
            var wrappedOtherInfo = new BitString(0);

            if (derParams.PartyUInfo.BitLength > 0)
            {
                wrappedOtherInfo = AnsDerEncodingHelper.EncodePartyUInfo(derParams.PartyUInfo);
            }
            if (derParams.PartyVInfo.BitLength > 0)
            {
                wrappedOtherInfo = BitString.ConcatenateBits(wrappedOtherInfo, AnsDerEncodingHelper.EncodePartyVInfo(derParams.PartyVInfo));
            }
            if (derParams.SuppPubInfo.BitLength > 0)
            {
                wrappedOtherInfo = BitString.ConcatenateBits(wrappedOtherInfo, AnsDerEncodingHelper.EncodeSuppPubInfo(derParams.SuppPubInfo));
            }
            if (derParams.SuppPrivInfo.BitLength > 0)
            {
                wrappedOtherInfo = BitString.ConcatenateBits(wrappedOtherInfo, AnsDerEncodingHelper.EncodeSuppPrivInfo(derParams.SuppPrivInfo));
            }

            // OuterWrapper (Sequence) || length || content
            var fullEncoding = AnsDerEncodingHelper.EncodeSequence(algorithmIdentifier.ConcatenateBits(wrappedOtherInfo));

            return(fullEncoding);
        }
Exemple #7
0
        public KdfResult DeriveKey(IAns942Parameters param)
        {
            if (!(param is DerAns942Parameters derParams))
            {
                return(new KdfResult("Unable to parse der parameters"));
            }

            if (derParams.KeyLen <= 0 || derParams.KeyLen > 65536)
            {
                return(new KdfResult($"KeyLen must be between [1, 65536]. Value given was: {derParams.KeyLen}"));
            }

            var d       = (int)System.Math.Ceiling(derParams.KeyLen / (decimal)_sha.HashFunction.OutputLen);
            var h       = new BitString(0);
            var counter = BitString.To32BitString(0);

            for (var i = 1; i <= d; i++)
            {
                // Increment Counter
                counter = counter.BitStringAddition(BitString.One());

                // Prepare ANS.1/DER encoded OtherInfo
                var derEncodedOtherInfo = DerEncode(derParams, counter);
                var str = derEncodedOtherInfo.ToHex();
                // H[i] = Hash(ZZ || otherInfo)
                h = h.ConcatenateBits(_sha.HashMessage(derParams.Zz.ConcatenateBits(derEncodedOtherInfo)).Digest);
            }

            return(new KdfResult(h.GetMostSignificantBits(derParams.KeyLen)));
        }
        public override PaddingResult Pad(int nlen, BitString message)
        {
            // 1. Message Hashing
            var hashedMessage = Sha.HashMessage(message).Digest;

            // 2. Hash Encapsulation
            var trailer = GetTrailer();

            // Header is always 4, trailer is always 16
            var paddingLen = nlen - Header.BitLength - Sha.HashFunction.OutputLen - trailer.BitLength;
            var padding    = GetPadding(paddingLen);

            // ERROR: Split the padding into two chunks and put the hashed message in the middle
            var firstChunkPadding  = padding.GetMostSignificantBits(paddingLen - 8);
            var secondChunkPadding = padding.GetLeastSignificantBits(8);

            var IR = Header.GetDeepCopy();

            IR = BitString.ConcatenateBits(IR, firstChunkPadding);
            IR = BitString.ConcatenateBits(IR, hashedMessage);
            IR = BitString.ConcatenateBits(IR, secondChunkPadding);
            IR = BitString.ConcatenateBits(IR, trailer);

            if (IR.BitLength != nlen)
            {
                return(new PaddingResult("Improper length for IR"));
            }

            return(new PaddingResult(IR));
        }
Exemple #9
0
        // Override with good or bad padding methods
        public virtual PaddingResult Pad(int nlen, BitString message)
        {
            // 1. Message Hashing
            var hashedMessage = Sha.HashMessage(message).Digest;

            // 2. Hash Encapsulation
            var trailer = GetTrailer();

            // Header is always 4, trailer is always 16
            var paddingLen = nlen - Header.BitLength - Sha.HashFunction.OutputLen - trailer.BitLength;
            var padding    = GetPadding(paddingLen);

            var IR = Header.GetDeepCopy();

            IR = BitString.ConcatenateBits(IR, padding);
            IR = BitString.ConcatenateBits(IR, hashedMessage);
            IR = BitString.ConcatenateBits(IR, trailer);

            if (IR.BitLength != nlen)
            {
                return(new PaddingResult("Improper length for IR"));
            }

            return(new PaddingResult(IR));
        }
        private DrbgStatus InstantiateNoDf(BitString entropyInput, BitString personalizationString)
        {
            // 1. temp = len(personalization_string)
            int temp = personalizationString.BitLength;

            // 2. If (temp < seedlen) then personalization_string =
            // personalization_string || 0^(seedlen - temp)
            if (temp < CounterAttributes.SeedLength)
            {
                personalizationString = personalizationString
                                        .ConcatenateBits(new BitString(CounterAttributes.SeedLength - temp)); // Add zeroes to bitstring to make it equal the SeedLength
            }

            // 3. seed_material = entropy_input xor personalization_string
            BitString seedMaterial = entropyInput.XOR(personalizationString);

            // 4. Key = 0^keylen
            Key = new BitString(CounterAttributes.KeyLength);

            // 5. V = 0^outlen
            V = new BitString(CounterAttributes.OutputLength);

            // 6. (Key, V) = Update(seed_material, Key, V)
            // NOTE: update uses member variables m_Key and m_V
            // for input and output of Key and V
            Update(seedMaterial);

            ReseedCounter = 1;

            return(DrbgStatus.Success);
        }
Exemple #11
0
        /// <summary>
        /// Call this method to format correctly for KMAC
        /// </summary>
        /// <param name="message">BitString representation of message</param>
        /// <param name="capacity">Capacity</param>
        /// <param name="customizationString">Character string for customization</param>
        /// <returns>Formatted message before calling Keccak</returns>
        public static BitString FormatMessage(BitString message, BitString key, int capacity, int macLength, bool xof)
        {
            var macLengthBitString = new BitString(new System.Numerics.BigInteger(macLength));

            BitString newMessage;

            if (capacity == 256)
            {
                newMessage = Sha3DerivedHelpers.Bytepad(Sha3DerivedHelpers.EncodeString(key), new BitString("A8")); // "A8" is 164 (the rate)
            }
            else                                                                                                    // capacity == 512
            {
                newMessage = Sha3DerivedHelpers.Bytepad(Sha3DerivedHelpers.EncodeString(key), new BitString("88")); // "88" is 136 (the rate)
            }

            if (xof)
            {
                var concatenatedMessageEncode = Sha3DerivedHelpers.SafeConcatenation(message, Sha3DerivedHelpers.RightEncode(BitString.Zeroes(8)));
                newMessage = BitString.ConcatenateBits(newMessage, concatenatedMessageEncode);
            }
            else
            {
                var concatenatedMessageEncode = Sha3DerivedHelpers.SafeConcatenation(message, Sha3DerivedHelpers.RightEncode(macLengthBitString));
                newMessage = BitString.ConcatenateBits(newMessage, concatenatedMessageEncode);
            }

            return(newMessage);
        }
Exemple #12
0
        public OtherInfo(
            IEntropyProvider entropyProvider,
            string otherInfoPattern,
            int otherInfoLength,
            KeyAgreementRole thisPartyKeyAgreementRole,
            PartyOtherInfo thisPartyOtherInfo,
            PartyOtherInfo otherPartyOtherInfo
            )
        {
            _thisPartyKeyAgreementRole = thisPartyKeyAgreementRole;
            _thisPartyOtherInfo        = thisPartyOtherInfo;
            _otherPartyOtherInfo       = otherPartyOtherInfo;

            // split the pattern into pieces
            var pieces = otherInfoPattern.Split("||".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);

            foreach (var piece in pieces)
            {
                var workingPiece = piece.Replace("||", "");
                _otherInfo = _otherInfo.ConcatenateBits(ConcatenatePieceOntoOtherInfo(workingPiece));
            }

            // Add entropy to hit otherInfoLength
            _otherInfo = _otherInfo.ConcatenateBits(entropyProvider.GetEntropy(otherInfoLength - _otherInfo.BitLength));

            _otherInfo = _otherInfo.GetMostSignificantBits(otherInfoLength);
        }
Exemple #13
0
        // Public for use in HashConditioningComponent
        public DrbgResult Hash_Df(BitString data, int bitsToReturn)
        {
            // 0
            if (bitsToReturn > 255 * HashAttributes.OutputLength)
            {
                throw new ArgumentException("Requesting too many bits to return");
            }

            // 1
            var temp = new BitString(0);

            // 2
            var len = bitsToReturn.CeilingDivide(HashAttributes.OutputLength);

            // 3
            var counter = new BitString("01");

            // 4
            for (var i = 0; i < len; i++)
            {
                // 4.1
                var dataToHash = counter.ConcatenateBits(BitString.To32BitString(bitsToReturn)).ConcatenateBits(data);
                temp = temp.ConcatenateBits(_sha.HashMessage(dataToHash).Digest);

                // 4.2
                counter = counter.BitStringAddition(BitString.One());
            }

            // 5
            var requestedBits = temp.MSBSubstring(0, bitsToReturn);

            // 6
            return(new DrbgResult(requestedBits));
        }
        public override PaddingResult Pad(int nlen, BitString message)
        {
            // 1. Message Hashing
            var hashedMessage = Sha.HashMessage(message).Digest;

            // 2. Hash Encapsulation
            var trailer = new BitString("66CC");    // ERROR: The first byte of the trailer is unexpected

            // Header is always 4, trailer is always 16
            var paddingLen = nlen - Header.BitLength - Sha.HashFunction.OutputLen - trailer.BitLength;
            var padding    = GetPadding(paddingLen);

            var IR = Header.GetDeepCopy();

            IR = BitString.ConcatenateBits(IR, padding);
            IR = BitString.ConcatenateBits(IR, hashedMessage);
            IR = BitString.ConcatenateBits(IR, trailer);      // ERROR: Change the trailer to something else

            if (IR.BitLength != nlen)
            {
                return(new PaddingResult("Improper length for IR"));
            }

            return(new PaddingResult(IR));
        }
        protected override BitString ComputeSharedSecret(OtherPartySharedInformation <EccDomainParameters, EccKeyPair> otherPartyInformation)
        {
            // static secret composed of both parties static key parts
            var staticSecret = _diffieHellman.GenerateSharedSecretZ(
                DomainParameters,
                StaticKeyPair,
                otherPartyInformation.StaticPublicKey
                ).SharedSecretZ;

            // differing ephemeralSecret logic depending on key agreement role
            BitString ephemeralSecret;

            if (SchemeParameters.KeyAgreementRole == KeyAgreementRole.InitiatorPartyU)
            {
                ephemeralSecret = _diffieHellman.GenerateSharedSecretZ(
                    DomainParameters,
                    EphemeralKeyPair,
                    otherPartyInformation.StaticPublicKey
                    ).SharedSecretZ;
            }
            else
            {
                ephemeralSecret = _diffieHellman.GenerateSharedSecretZ(
                    DomainParameters,
                    StaticKeyPair,
                    otherPartyInformation.EphemeralPublicKey
                    ).SharedSecretZ;
            }

            // Shared secret is composed (Z_e || Z_s)
            return(BitString.ConcatenateBits(ephemeralSecret, staticSecret));
        }
Exemple #16
0
        public KdfResult DeriveKey(IAns942Parameters param)
        {
            if (!(param is ConcatAns942Parameters concatParams))
            {
                return(new KdfResult("Unable to parse concat parameters"));
            }

            if (concatParams.KeyLen <= 0 || concatParams.KeyLen > 65536)
            {
                return(new KdfResult($"KeyLen must be between [1, 65536]. Value given was: {concatParams.KeyLen}"));
            }

            var d       = (int)System.Math.Ceiling(concatParams.KeyLen / (decimal)_sha.HashFunction.OutputLen);
            var counter = BitString.To32BitString(1);
            var h       = new BitString(0);

            for (var i = 1; i <= d; i++)
            {
                // H[i] = Hash(ZZ || counter || otherInfo)
                var hashInput = concatParams.Zz.ConcatenateBits(counter).ConcatenateBits(concatParams.OtherInfo);
                h = h.ConcatenateBits(_sha.HashMessage(hashInput).Digest);

                counter = counter.BitStringAddition(BitString.One());
            }

            return(new KdfResult(h.GetMostSignificantBits(concatParams.KeyLen)));
        }
Exemple #17
0
        public TlsKdfResult DeriveKey(BitString preMasterSecret, BitString clientHelloRandom, BitString serverHelloRandom, BitString clientRandom, BitString serverRandom, int keyBlockLength)
        {
            var masterSecret = Prf(preMasterSecret, MasterSecretLabel(), clientHelloRandom.ConcatenateBits(serverHelloRandom), 384);
            var keyBlock     = Prf(masterSecret, "key expansion", serverRandom.ConcatenateBits(clientRandom), keyBlockLength);

            return(new TlsKdfResult(masterSecret, keyBlock));
        }
Exemple #18
0
        private void Update(BitString providedData)
        {
            // 1
            var dataToHmac = V.ConcatenateBits(new BitString("00")).ConcatenateBits(providedData);

            Key = _hmac.Generate(Key, dataToHmac).Mac;

            // 2
            V = _hmac.Generate(Key, V).Mac;

            // 3
            if (providedData.BitLength == 0)
            {
                return;
            }

            // 4
            dataToHmac = V.ConcatenateBits(new BitString("01")).ConcatenateBits(providedData);
            Key        = _hmac.Generate(Key, dataToHmac).Mac;

            // 5
            V = _hmac.Generate(Key, V).Mac;

            // 6
            return;
        }
Exemple #19
0
        protected override BitString GetEphemeralDataFromKeyContribution(ISecretKeyingMaterial secretKeyingMaterial)
        {
            if (secretKeyingMaterial.EphemeralKeyPair != null)
            {
                var domainParam = (EccDomainParameters)secretKeyingMaterial.DomainParameters;
                var exactLength = CurveAttributesHelper.GetCurveAttribute(domainParam.CurveE.CurveName).DegreeOfPolynomial;;

                var ephemKey = (EccKeyPair)secretKeyingMaterial.EphemeralKeyPair;

                if (ephemKey.PublicQ.X != 0)
                {
                    return(BitString.ConcatenateBits(
                               SharedSecretZHelper.FormatEccSharedSecretZ(ephemKey.PublicQ.X, exactLength),
                               SharedSecretZHelper.FormatEccSharedSecretZ(ephemKey.PublicQ.Y, exactLength)
                               ));
                }
            }

            if (secretKeyingMaterial.EphemeralNonce != null && secretKeyingMaterial.EphemeralNonce?.BitLength != 0)
            {
                return(secretKeyingMaterial.EphemeralNonce);
            }

            return(secretKeyingMaterial.DkmNonce);
        }
Exemple #20
0
        public byte[] HandleFinalFullPayloadBlockDecryption(BitString payload, IBlockCipherEngine engine, int numberOfBlocks, int originalPayloadBitLength)
        {
            // Decrypt the last full payload block (when there is more than one block)
            if (numberOfBlocks > 1)
            {
                var originalPayloadPaddedToBlockSize = payload.PadToModulus(engine.BlockSizeBits).ToBytes();

                // Decrypt the last full payload block (in this case the second to last block)
                var secondToLastBlock           = new byte[engine.BlockSizeBytes];
                var secondToLastBlockStartIndex = (numberOfBlocks - 2) * engine.BlockSizeBytes;
                Array.Copy(originalPayloadPaddedToBlockSize, secondToLastBlockStartIndex, secondToLastBlock, 0, engine.BlockSizeBytes);

                var decryptedSecondToLastBlockBuffer = new byte[engine.BlockSizeBytes];

                engine.ProcessSingleBlock(secondToLastBlock, decryptedSecondToLastBlockBuffer, 0);

                var decryptedBlock = new BitString(decryptedSecondToLastBlockBuffer);

                // Pad the payload to the nearest multiple of the block size using the last B−M bits of block cipher decryption of the second-to-last ciphertext block.
                var amountToPad = (engine.BlockSizeBits - payload.BitLength % engine.BlockSizeBits);
                if (amountToPad > 0)
                {
                    payload = payload.ConcatenateBits(BitString.Substring(decryptedBlock, 0, amountToPad));
                }

                var payloadBytes = payload.ToBytes();
                TransformText(payloadBytes, engine, numberOfBlocks, originalPayloadBitLength);

                payload = new BitString(payloadBytes);
                return(payload.ToBytes());
            }

            return(payload.ToBytes());
        }
Exemple #21
0
        protected override BitString ComputeSharedSecret(ISecretKeyingMaterial otherPartyKeyingMaterial)
        {
            var domainParameters = (EccDomainParameters)ThisPartyKeyingMaterial.DomainParameters;

            // static secret composed of both parties static key parts
            var staticSecret = _diffieHellman.GenerateSharedSecretZ(
                domainParameters,
                (EccKeyPair)ThisPartyKeyingMaterial.StaticKeyPair,
                (EccKeyPair)otherPartyKeyingMaterial.StaticKeyPair
                ).SharedSecretZ;

            // differing ephemeralSecret logic depending on key agreement role
            BitString ephemeralSecret;

            if (SchemeParameters.KeyAgreementRole == KeyAgreementRole.InitiatorPartyU)
            {
                ephemeralSecret = _diffieHellman.GenerateSharedSecretZ(
                    domainParameters,
                    (EccKeyPair)ThisPartyKeyingMaterial.EphemeralKeyPair,
                    (EccKeyPair)otherPartyKeyingMaterial.StaticKeyPair
                    ).SharedSecretZ;
            }
            else
            {
                ephemeralSecret = _diffieHellman.GenerateSharedSecretZ(
                    domainParameters,
                    (EccKeyPair)ThisPartyKeyingMaterial.StaticKeyPair,
                    (EccKeyPair)otherPartyKeyingMaterial.EphemeralKeyPair
                    ).SharedSecretZ;
            }

            // Shared secret is composed (Z_e || Z_s)
            return(BitString.ConcatenateBits(ephemeralSecret, staticSecret));
        }
Exemple #22
0
        // returns null if keyPair is exhausted
        public async Task <HssSignatureResult> GenerateHssSignatureAsync(BitString msg, HssKeyPair keyPair, int advanced = 0)
        {
            // 1. If the message-signing key prv[L - 1] is exhausted, regenerate that key pair, together with any
            //    parent key pairs that might be necessary. If the root key pair is exhausted, then the HSS key pair is
            //    exhausted and MUST NOT generate any more signatures.
            keyPair = await UpdateKeyPairAsync(keyPair, advanced);

            if (keyPair.Expired)
            {
                return(new HssSignatureResult("Key expired."));
            }

            // 2. Sign the message.
            var sig = _lms[_lms.Length - 1].GenerateLmsSignature(msg, keyPair.PrivateKey.PrivateKeys[_lms.Length - 1]);

            // 3. Create the list of signed public keys.
            var signedPubKey = new BitString("");

            for (int i = 0; i < _lms.Length - 1; i++)
            {
                signedPubKey = signedPubKey.ConcatenateBits(keyPair.PrivateKey.Signatures[i])
                               .ConcatenateBits(keyPair.PrivateKey.PublicKeys[i + 1]);
            }

            // 4. Return u32str(L-1) || signed_pub_key[0] || ... || signed_pub_key[L - 2] || sig[L - 1]
            return(new HssSignatureResult(new BitString(_lms.Length - 1, 32).ConcatenateBits(signedPubKey).ConcatenateBits(sig)));
        }
Exemple #23
0
        private BitString HashGen(BitString v, int bitsToReturn)
        {
            // 1
            var m = bitsToReturn / HashAttributes.OutputLength + (bitsToReturn % HashAttributes.OutputLength != 0 ? 1 : 0);

            // 2
            var data = v.GetDeepCopy();

            // 3
            var W = new BitString(0);

            // 4
            for (var i = 0; i < m; i++)
            {
                // 4.1
                var w = _sha.HashMessage(data).Digest;

                // 4.2
                W = W.ConcatenateBits(w);

                // 4.3
                data = data.BitStringAddition(BitString.One()).GetLeastSignificantBits(HashAttributes.SeedLength);
            }

            // 5
            var returnedBits = W.MSBSubstring(0, bitsToReturn);

            // 6
            return(returnedBits);
        }
        protected override BitString Wrap(BitString K, BitString S, bool wrapWithInverseCipher)
        {
            // 0. Pre-conditions
            var n = S.BitLength / 32;

            if ((n < 3) || (S.BitLength % 32 != 0))
            {
                throw new ArgumentException($"Invalid {nameof(S)} length.");
            }

            var keylen = K.BitLength;
            var K2     = K.GetDeepCopy();
            //if (keylen == 192)
            //{
            //    // Convert to 168 bits because TDES Block encrypt takes 168 bits
            //    K2 = to168BitKey(K);
            //    keylen = K2.BitLength;
            //}
            //else
            //{
            //    K2 = K;
            //}
            //if (keylen != 168)
            //{
            //    throw new ArgumentException($"Invalid {nameof(keylen)}");
            //}

            // 1. Initialize variables
            // 1.a) Let s = 6(n-1)
            int s = 6 * (n - 1);
            // 1.b) Let S1,S2,...,Sn be the semi-blocks s.t. S=S1 || S2 || ... || Sn
            // 1.c) Let A0 = S1
            BitString A = S.GetMostSignificantBits(32);
            // 1.d) For i=2,...,n: let Ri0 = Si
            BitString R2n = S.GetLeastSignificantBits(S.BitLength - 32);

            // 2. Calculate the intermediate values.  For t = 1,...,s update variables
            //    as follows:
            for (int t = 1; t <= s; ++t)
            {
                // a) A^t = MSB32(CIPH_K(A^t-1 || R2^t-1)) xor [t]32
                BitString R2 = R2n.GetMostSignificantBits(32);

                //BitString t32 = to_bitstring32((unsigned long long)t);
                BitString t32 = BitString.To64BitString(t).GetLeastSignificantBits(32);

                var       param   = new ModeBlockCipherParameters(BlockCipherDirections.Encrypt, K2, A.ConcatenateBits(R2), wrapWithInverseCipher);
                BitString block_t = Cipher.ProcessPayload(param).Result;
                A = block_t.GetMostSignificantBits(32).XOR(t32);
                // b) For i=2,...,n: Ri^t = Ri+1^t-1
                // c) Rn^t = LSB32(CIPH_K(CIPH_K(A^t-1 || R2^t-1)))
                R2n = R2n.GetLeastSignificantBits(R2n.BitLength - 32).ConcatenateBits(block_t.GetLeastSignificantBits(32));
            }

            // 3. Output the results:
            // a) Let C1 = A^s
            // b) For i=2,...,n: Ci = Ri^s
            // c) Return C1 || C2 || ... || Cn
            return(A.ConcatenateBits(R2n));
        }
        // Question: Is it a hard restriction that the hash within HMAC is the same used within the signature process?
        public BigInteger GetNonce(BigInteger privateD, BigInteger hashedMessage, BigInteger orderN)
        {
            // 1.3
            var seedMaterial = new BitString(privateD).PadToModulusMsb(32).ConcatenateBits(new BitString(hashedMessage).PadToModulusMsb(32));

            // 1.4
            var key = BitString.Zeroes(_hmac.OutputLength);

            // 1.5
            var v = _01bits.GetMostSignificantBits(_hmac.OutputLength);

            // 1.6
            key = _hmac.Generate(key, v.ConcatenateBits(BitString.ConcatenateBits(BitString.Zeroes(8), seedMaterial))).Mac;

            // 1.7
            v = _hmac.Generate(key, v).Mac;

            // 1.8
            key = _hmac.Generate(key, v.ConcatenateBits(BitString.ConcatenateBits(new BitString("01"), seedMaterial))).Mac;

            // 1.9
            v = _hmac.Generate(key, v).Mac;

            // 2
            var nlen = orderN.ExactBitLength();

            // 3
            BigInteger k = 0;

            while (k == 0 || k >= orderN)
            {
                // 4.1
                var tmp = new BitString(0);

                // 4.2
                while (tmp.BitLength < nlen)
                {
                    v   = _hmac.Generate(key, v).Mac;
                    tmp = tmp.ConcatenateBits(v);
                }

                // 4.3
                k = tmp.GetMostSignificantBits(nlen).ToPositiveBigInteger();

                // 4.4
                if (k > 0 && k < orderN)
                {
                    return(k);
                }

                // 4.5
                key = _hmac.Generate(key, v.ConcatenateBits(BitString.Zeroes(8))).Mac;

                // 4.6
                v = _hmac.Generate(key, v).Mac;
            }

            return(k);
        }
Exemple #26
0
        private BitString PseudoRandomFunction(BitString k, BitString h, char letter, BitString sessionId, int L)
        {
            var N         = L.CeilingDivide(_hash.HashFunction.OutputLen);
            var charArray = new[] { letter };

            var message = k.ConcatenateBits(h).ConcatenateBits(new BitString(Encoding.ASCII.GetBytes(charArray))).ConcatenateBits(sessionId);
            var kOut    = _hash.HashMessage(message).Digest;

            for (var i = 0; i < N; i++)
            {
                var hashIn = k.ConcatenateBits(h).ConcatenateBits(kOut);
                var kI     = _hash.HashMessage(hashIn).Digest;
                kOut = kOut.ConcatenateBits(kI);
            }

            return(kOut.GetMostSignificantBits(L));
        }
Exemple #27
0
        public BigInteger GetFullSeed()
        {
            var seedBS  = new BitString(Seed).PadToModulusMsb(32);
            var pSeedBS = new BitString(PSeed).PadToModulusMsb(32);
            var qSeedBS = new BitString(QSeed).PadToModulusMsb(32);

            return(BitString.ConcatenateBits(seedBS, BitString.ConcatenateBits(pSeedBS, qSeedBS)).ToPositiveBigInteger());
        }
        protected override BitString WrapInverse(BitString K, BitString C, bool wrappedWithInverseCipher)
        {
            // 0. Pre-conditions
            int n = C.BitLength / 32;

            if ((n < 3) || (C.BitLength % 32 != 0))
            {
                throw new ArgumentException($"Invalid {nameof(C)} length.");
            }
            int keyLength = K.BitLength;
            var K2        = K.GetDeepCopy();
            //if (keyLength == 192)
            //{
            //    // Convert to 168 bits because TDES Block encrypt takes 168 bits
            //    K2 = to168BitKey(K);
            //    keyLength = K2.BitLength;
            //}
            //else
            //{
            //    K2 = K;
            //}
            //if (keyLength != 168)
            //{
            //    throw new ArgumentException($"Invalid {nameof(keyLength)}");
            //}

            // 1. Initialize variables
            // 1.a) Let s = 6(n-1)
            int s = 6 * (n - 1);
            // 1.b) Let C1,C2,...,Cn be the semi-blocks s.t. C=C1 || C2 || ... || Cn
            // 1.c) Let As = C1
            BitString A = C.GetMostSignificantBits(32);
            // 1.d) For i=2,...,n: let Ri0 = Ci
            BitString R2n = C.GetLeastSignificantBits(C.BitLength - 32);


            // 2. Calculate the intermediate values.  For t = s, s-1, ..., 1,
            //    update the variables as follows:
            for (int t = s; t >= 1; --t)
            {
                // a) A^t-1 = MSB(CIPH^-1K((A^t xor [t]32) || Rn^t))
                BitString t32 = BitString.To64BitString(t).GetLeastSignificantBits(32);
                BitString Rn  = R2n.GetLeastSignificantBits(32);

                var       param   = new ModeBlockCipherParameters(BlockCipherDirections.Decrypt, K2, A.XOR(t32).ConcatenateBits(Rn), wrappedWithInverseCipher);
                BitString block_t = Cipher.ProcessPayload(param).Result;
                A = block_t.GetMostSignificantBits(32);
                // b) R2^t-1 = LSB(CIPH^-1K((A^t xor [t]32) || Rn^t))
                // c) For i=2,...,n-1, Ri+1^t-1 = Ri^t
                R2n = block_t.GetLeastSignificantBits(32).ConcatenateBits(R2n.GetMostSignificantBits(R2n.BitLength - 32));
            }

            // 3. Output the results:
            // 3.a) Let S1 = A0
            // 3.b) For i=2,...,n: Si = Ri0
            // 3.c) Return S1 || S2 || ... || Sn
            return(A.ConcatenateBits(R2n));
        }
Exemple #29
0
        public EdSignatureResult Sign(EdDomainParameters domainParameters, EdKeyPair keyPair, BitString message, BitString context, bool preHash = false)
        {
            Sha = domainParameters.Hash;

            // If preHash version, then the message becomes the hash of the message
            if (preHash)
            {
                message = Sha.HashMessage(message, 512).Digest;
            }

            // 1. Hash the private key
            var hashResult = HashPrivate(domainParameters, keyPair.PrivateD);

            // 2. Compute r
            // Determine dom. Empty if ed25519. Different for preHash function
            BitString dom;
            if (preHash)
            {
                dom = domainParameters.CurveE.CurveName == Curve.Ed448 ? Dom4(1, context) : Dom2(1, context);
            }
            else
            {
                dom = domainParameters.CurveE.CurveName == Curve.Ed448 ? Dom4(0, context) : new BitString("");
            }

            // Hash (dom4 || Prefix || message)
            var rBits = Sha.HashMessage(BitString.ConcatenateBits(dom, BitString.ConcatenateBits(hashResult.HDigest2, message)), 912).Digest;

            // Convert rBits to little endian and mod order n
            var r = BitString.ReverseByteOrder(rBits).ToPositiveBigInteger() % domainParameters.CurveE.OrderN;

            // 3. Compute [r]G. R is the encoding of [r]G
            var rG = domainParameters.CurveE.Multiply(domainParameters.CurveE.BasePointG, r);

            // Encode the point rG into a b-bit bitstring
            var R = domainParameters.CurveE.Encode(rG);

            // 4. Define S
            // Hash (dom4 || R || Q || M). Need to use dom4 if ed448
            var hashData = BitString.ConcatenateBits(keyPair.PublicQ, message);
            hashData = BitString.ConcatenateBits(dom, BitString.ConcatenateBits(R, hashData));
            var hash = Sha.HashMessage(hashData, 912).Digest;

            // Convert hash to int from little endian and mod order n
            var hashInt = BitString.ReverseByteOrder(hash).ToPositiveBigInteger() % domainParameters.CurveE.OrderN;

            // Determine s as done in key generation
            var s = NumberTheory.Pow2(domainParameters.CurveE.VariableN) + hashResult.Buffer.ToPositiveBigInteger();

            // Calculate S as an BigInteger
            var Sint = (r + (hashInt * s)).PosMod(domainParameters.CurveE.OrderN);

            // Encode S in little endian
            var S = BitString.ReverseByteOrder(new BitString(Sint, domainParameters.CurveE.VariableB));

            // 5. Form the signature by concatenating R and S
            return new EdSignatureResult(new EdSignature(R, S));
        }
Exemple #30
0
        public override SymmetricCipherResult Encrypt(BitString key, BitString plainText, bool wrapWithInverseCipher)
        {
            // 1. Let ICV1 = 0xA6A6A6A6A6A6A6A6
            // 2. Let S = ICV1 || P
            // 3. Return C = W(S)
            BitString c = Wrap(key, Icv1.ConcatenateBits(plainText), wrapWithInverseCipher);

            return(new SymmetricCipherResult(c));
        }