/// <summary>
        /// Used by the initiator. It first verifies that the incoming token is well-formed, and then removes the previously applied mask.
        /// </summary>
        /// <param name="ecParameters">Curve parameters</param>
        /// <param name="K">The public key point for the token scheme</param>
        /// <param name="P">Masked point initially submitted to the token service</param>
        /// <param name="Q">Signed masked point returned from the token service</param>
        /// <param name="c">Claimed challenge from the Chaum-Pedersen proof</param>
        /// <param name="z">Response from the Chaum-Pedersen proof</param>
        /// <param name="r">Masking of the initial point</param>
        /// <returns>A randomised signature W on the point chosen by the initiator</returns>
        public ECPoint RandomiseToken(X9ECParameters ecParameters, ECPoint K, ECPoint P, ECPoint Q, BigInteger c, BigInteger z, BigInteger r)
        {
            ECCurve?curve = ecParameters.Curve;

            // Check that P is a valid point on the currect curve
            if (ECPointVerifier.PointIsValid(P, curve) == false)
            {
                throw new AnonymousTokensException("P is not a valid point on the curve");
            }

            // Check that Q is a valid point on the currect curve
            if (ECPointVerifier.PointIsValid(Q, curve) == false)
            {
                throw new AnonymousTokensException("Q is not a valid point on the curve");
            }

            // Verify the proof (c,z).
            if (!VerifyProof(ecParameters, K, P, Q, c, z))
            {
                throw new AnonymousTokensException("Chaum-Pedersen proof is invalid");
            }

            // Removing the initial mask r. W = (1/r)*Q = k*T.
            BigInteger?rInverse = r.ModInverse(ecParameters.Curve.Order);
            ECPoint?   W        = Q.Multiply(rInverse);

            return(W);
        }
Exemple #2
0
        /// <summary>
        /// Used by the token verifier. It recreates the initial point from the initiator, signs it, and verifies that they are equal.
        /// </summary>
        /// <param name="k">The private key for the token scheme</param>
        /// <param name="curve">Curve parameters</param>
        /// <param name="t">Seed for the initial point chosen by the initiator</param>
        /// <param name="W">Token received from the initiator</param>
        /// <returns>True if the token is valid, otherwise false</returns>
        public async Task <bool> VerifyTokenAsync(
            BigInteger k,
            ECCurve curve,
            byte[] t,
            ECPoint W)
        {
            // Check if token t is received earlier
            if (await _seedStore.ExistsAsync(t))
            {
                return(false);
            }

            // Check that W is a valid point on the currect curve
            if (ECPointVerifier.PointIsValid(W, curve) == false)
            {
                throw new AnonymousTokensException("W is not a valid point on the curve");
            }

            await _seedStore.SaveAsync(t);

            ECPoint?T = ECCurveHash.HashToWeierstrassCurve(curve, t);

            if (T == null)
            {
                return(false);
            }

            ECPoint?V = T.Multiply(k);

            return(V.Equals(W));
        }
        public void PointIsValid_PointIsOnCurve_ReturnsTrue()
        {
            // Arrange
            var curve = Fp.curve;
            var point = Fp.p[0];

            // Act
            var actual = ECPointVerifier.PointIsValid(point, curve);

            // Assert
            Assert.True(actual);
        }
        public void PointIsValid_PointIsNotOnCurve_ReturnsFalse()
        {
            // Arrange
            var x9    = ECNamedCurveTable.GetByName("prime239v1");
            var curve = x9.Curve;
            var point = Fp.p[0];

            // Act
            var actual = ECPointVerifier.PointIsValid(point, curve);

            // Assert
            Assert.False(actual);
        }
        /// <summary>
        /// Used by the token service. Signs the point submitted by the initiator in order to create a token, and outputs a proof of validity.
        /// </summary>
        /// <param name="k">The private key for the token scheme</param>
        /// <param name="K">The public key for the token scheme</param>
        /// <param name="ecParameters">Curve parameters</param>
        /// <param name="P">Point submitted by the app</param>
        /// <returns>A signed point Q and a Chaum-Pedersen proof (c,z) proving that the point is signed correctly</returns>
        public (ECPoint Q, BigInteger c, BigInteger z) GenerateToken(
            BigInteger k,
            ECPoint K,
            X9ECParameters ecParameters,
            ECPoint P)
        {
            ECCurve?curve = ecParameters.Curve;

            // Check that P is a valid point on the currect curve
            if (ECPointVerifier.PointIsValid(P, curve) == false)
            {
                throw new AnonymousTokensException("P is not a valid point on the curve");
            }

            // Compute Q = k*P
            ECPoint?Q = P.Multiply(k);

            // Chaum-Pedersen proof of correct signature
            var(c, z) = CreateProof(ecParameters, k, K, P, Q);

            return(Q, c, z);
        }