Пример #1
0
        /// <inheritdoc />
        /// <remarks>
        /// Base Mode Specification: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-voprf-06.txt#section-3.4.3.3
        /// Input:
        ///     ClientInput input
        ///     Scalar blind
        ///     SerializedElement evaluatedElement
        /// Output:
        ///     opaque output[Nh]
        /// def Finalize(input, blind, evaluatedElement):
        ///     unblindedElement = Unblind(blind, evaluatedElement)
        ///     finalizeDST = "VOPRF06-Finalize-" || self.contextString
        ///     hashInput = I2OSP(len(input), 2) || input ||
        ///                 I2OSP(len(unblindedElement), 2) || unblindedElement ||
        ///                 I2OSP(len(finalizeDST), 2) || finalizeDST
        ///     return Hash(hashInput)
        /// </remarks>
        public byte[] Finalise(byte[] clientInput, byte[] blindScalar, byte[] serverEvaluatedGroupElement)
        {
            // unblindedElement = Unblind(blind, evaluatedElement)
            byte[] unblindedGroupElement = Unblind(blindScalar, serverEvaluatedGroupElement);

            // DST, a domain separation tag
            // as per https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-voprf-06.txt#section-5.1
            // finalizeDST = "VOPRF06-Finalize-" || self.contextString
            byte[] finaliseDST = CipherSuite.CreateDomainSeparationTag("Finalize");

            // hashInput = I2OSP(len(input), 2) || input ||
            //             I2OSP(len(unblindedElement), 2) || unblindedElement ||
            //             I2OSP(len(finalizeDST), 2) || finalizeDST
            byte[] hashInput = ByteArrayUtils.Concatenate(new List <byte[]>
            {
                BigEndianUtils.ConvertIntegerToOrdinalStringPrimitive(clientInput.Length, 2),
                clientInput,
                BigEndianUtils.ConvertIntegerToOrdinalStringPrimitive(unblindedGroupElement.Length, 2),
                unblindedGroupElement,
                BigEndianUtils.ConvertIntegerToOrdinalStringPrimitive(finaliseDST.Length, 2),
                finaliseDST
            });

            // return Hash(hashInput)
            return(CipherSuite.HashFunction.HashData(hashInput));
        }
Пример #2
0
 public void WhenI2OSPIsPerformedWithAnOutputLengthAndOffsetThatIsSmallerThanNeededForTheGivenByteArray()
 {
     ExpectedException.ExpectedType             = typeof(ArithmeticException);
     ExpectedException.MessageShouldContainText = "too large";
     byte[] result = new byte[3];
     Try(() => BigEndianUtils.ConvertIntegerToOrdinalStringPrimitive(944, 2, ref result, 2));
 }
Пример #3
0
 public void WhenI2OSPIsPerformedWithMultipleUnsignedIntegersAtDifferentOffsetsInTheSameByteArray()
 {
     _actualBytes = new byte[5];
     BigEndianUtils.ConvertIntegerToOrdinalStringPrimitive(944, 2, ref _actualBytes, 3); // offset 3 (positions 4 & 5)
     BigEndianUtils.ConvertIntegerToOrdinalStringPrimitive(257, 2, ref _actualBytes, 0); // offset 0
     _expectedBytes = new byte[] { 1, 1, 0, 3, 176 };                                    // 257 then 0 then 944 in base 256
 }
Пример #4
0
 public void WhenI2OSPIsPerformedWithAnOutputLengthThatIsSmallerThanNeeded()
 {
     ExpectedException.ExpectedType             = typeof(ArithmeticException);
     ExpectedException.MessageShouldContainText = "too large";
     Try(() => BigEndianUtils.ConvertIntegerToOrdinalStringPrimitive(944, 1));
 }
Пример #5
0
 public void WhenI2OSPIsPerformedWithAnExactlyCorrectOutputLength()
 {
     _actualBytes   = BigEndianUtils.ConvertIntegerToOrdinalStringPrimitive(944, 2).ToArray();
     _expectedBytes = new byte[] { 3, 176 }; // 944 in base 256
 }
Пример #6
0
 public void WhenI2OSPIsPerformedWithALargerOutputLengthThanIsNeeded()
 {
     _actualBytes   = BigEndianUtils.ConvertIntegerToOrdinalStringPrimitive(944, 3).ToArray();
     _expectedBytes = new byte[] { 0, 3, 176 }; // 944 in base 256
 }