コード例 #1
0
ファイル: EdDSA.cs プロジェクト: robinreigns/IoTGateway
        /// <summary>
        /// Signs data using the EdDSA algorithm.
        /// </summary>
        /// <param name="Data">Data to be signed.</param>
        /// <param name="PrivateKey">Private key.</param>
        /// <param name="Prefix">Prefix</param>
        /// <param name="HashFunction">Hash function to use</param>
        /// <param name="Curve">Elliptic curve</param>
        /// <returns>Signature</returns>
        public static byte[] Sign(Stream Data, byte[] PrivateKey, byte[] Prefix,
                                  HashFunctionStream HashFunction, EdwardsCurveBase Curve)
        {
            // 5.1.6 of RFC 8032

            int ScalarBytes = PrivateKey.Length;

            if (Prefix.Length != ScalarBytes)
            {
                throw new ArgumentException("Invalid prefix.", nameof(Prefix));
            }

            BigInteger   a = EllipticCurve.ToInt(PrivateKey);
            PointOnCurve P = Curve.ScalarMultiplication(PrivateKey, Curve.BasePoint, true);

            byte[] A = Encode(P, Curve);
            byte[] h;

            using (TemporaryFile TempFile = new TemporaryFile())    // dom2(F, C) = blank string
            {
                TempFile.Write(Prefix, 0, ScalarBytes);             // prefix

                Data.Position = 0;
                Data.CopyTo(TempFile);                              // PH(M)=M

                TempFile.Position = 0;
                h = HashFunction(TempFile);
            }

            BigInteger   r = BigInteger.Remainder(EllipticCurve.ToInt(h), Curve.Order);
            PointOnCurve R = Curve.ScalarMultiplication(r, Curve.BasePoint, true);

            byte[] Rs = Encode(R, Curve);

            using (TemporaryFile TempFile = new TemporaryFile())    // dom2(F, C) = blank string
            {
                TempFile.Write(Rs, 0, ScalarBytes);
                TempFile.Write(A, 0, ScalarBytes);

                Data.Position = 0;
                Data.CopyTo(TempFile);                              // PH(M)=M

                TempFile.Position = 0;
                h = HashFunction(TempFile);
            }

            BigInteger k = BigInteger.Remainder(EllipticCurve.ToInt(h), Curve.Order);
            BigInteger s = Curve.ModulusN.Add(r, Curve.ModulusN.Multiply(k, a));

            byte[] Bin = s.ToByteArray();
            if (Bin.Length != ScalarBytes)
            {
                Array.Resize <byte>(ref Bin, ScalarBytes);
            }

            byte[] Signature = new byte[ScalarBytes << 1];

            Array.Copy(Rs, 0, Signature, 0, ScalarBytes);
            Array.Copy(Bin, 0, Signature, ScalarBytes, ScalarBytes);

            return(Signature);
        }