Beispiel #1
0
        public static bool crypto_sign_verify(ReadOnlySpan <byte> sig, ReadOnlySpan <byte> m, ReadOnlySpan <byte> pk)
        {
            if ((sig[63] & 224) != 0)
            {
                return(false);
            }
            if (GroupOperations.ge_frombytes_negate_vartime(out var A, pk) != 0)
            {
                return(false);
            }

            var hasher = new Sha512();

            hasher.Update(sig.Slice(0, 32));
            hasher.Update(pk.Slice(0, 32));
            hasher.Update(m);
            Span <byte> h = stackalloc byte[64];

            hasher.Finish(h);

            ScalarOperations.sc_reduce(h);

            GroupOperations.ge_double_scalarmult_vartime(out var R, h, in A, sig.Slice(32, 32));
            Span <byte> checkr = stackalloc byte[32];

            GroupOperations.ge_tobytes(checkr, in R);
            var result = CryptoBytes.ConstantTimeEquals(checkr, sig, 32);

            CryptoBytes.Wipe(h);
            CryptoBytes.Wipe(checkr);
            return(result);
        }
Beispiel #2
0
        public static void crypto_sign_prehashed(
            byte[] sig,
            byte[] m, int mlen,
            byte[] sk,
            byte[] pk
            )
        {
            byte[]         r, hram;
            GroupElementP3 R;
            var            hasher = new Sha512();
            {
                hasher.Init();
                hasher.Update(sk, 32, 32);
                hasher.Update(m, 0, mlen);
                r = hasher.Finalize();

                ScalarOperations.sc_reduce(r);
                GroupOperations.ge_scalarmult_base(out R, r, 0);
                GroupOperations.ge_p3_tobytes(sig, 0, ref R);

                hasher.Init();
                hasher.Update(sig, 0, 32);
                hasher.Update(pk, 0, 32);
                hasher.Update(m, 0, mlen);
                hram = hasher.Finalize();

                ScalarOperations.sc_reduce(hram);
                var s = new byte[32];                //todo: remove allocation
                Array.Copy(sig, 32, s, 0, 32);
                ScalarOperations.sc_muladd(s, hram, sk, r);
                Array.Copy(s, 0, sig, 32, 32);
                CryptoBytes.Wipe(s);
            }
        }
Beispiel #3
0
        public void Wipe()
        {
            var bytes = (byte[])_bytes.Clone();

            CryptoBytes.Wipe(bytes);
            Assert.IsTrue(bytes.All(b => b == 0));
        }
        public void Wipe()
        {
            var bytes = (byte[])_bytes.Clone();

            CryptoBytes.Wipe(bytes);
            bytes.All(b => b == 0).Should().BeTrue();
        }
Beispiel #5
0
        /*public static void crypto_sign(
         *        byte[] sm, out int smlen,
         *         byte[] m, int mlen,
         *         byte[] sk
         *      )
         *      {
         *              byte[] az = new byte[64];
         *              byte[] r = new byte[64];
         *              byte[] hram = new byte[64];
         *              GroupElementP3 R;
         *              int i;
         *
         *              Helpers.crypto_hash_sha512(az, sk, 0, 32);
         *              az[0] &= 248;
         *              az[31] &= 63;
         *              az[31] |= 64;
         *
         *              smlen = mlen + 64;
         *              for (i = 0; i < mlen; ++i) sm[64 + i] = m[i];
         *              for (i = 0; i < 32; ++i) sm[32 + i] = az[32 + i];
         *              Helpers.crypto_hash_sha512(r, sm, 32, mlen + 32);
         *              for (i = 0; i < 32; ++i) sm[32 + i] = sk[32 + i];
         *
         *              ScalarOperations.sc_reduce(r);
         *              GroupOperations.ge_scalarmult_base(out R, r, 0);
         *              GroupOperations.ge_p3_tobytes(sm, 0, ref R);
         *
         *              Helpers.crypto_hash_sha512(hram, sm, 0, mlen + 64);
         *              ScalarOperations.sc_reduce(hram);
         *              var sm32 = new byte[32];
         *              Array.Copy(sm, 32, sm32, 0, 32);
         *              ScalarOperations.sc_muladd(sm32, hram, az, r);
         *              Array.Copy(sm32, 0, sm, 32, 32);
         *      }*/

        internal static void crypto_sign2(byte[] sig, int sigoffset, byte[] m, int moffset, int mlen, byte[] sk, int skoffset)
        {
            byte[] az;
            byte[] r;
            byte[] hram;
            var    hasher = new Sha512();
            {
                hasher.Update(sk, skoffset, 32);
                az = hasher.Finish();
                ScalarOperations.sc_clamp(az, 0);

                hasher.Init();
                hasher.Update(az, 32, 32);
                hasher.Update(m, moffset, mlen);
                r = hasher.Finish();

                ScalarOperations.sc_reduce(r);
                GroupOperations.ge_scalarmult_base(out GroupElementP3 R, r, 0);
                GroupOperations.ge_p3_tobytes(sig, sigoffset, ref R);

                hasher.Init();
                hasher.Update(sig, sigoffset, 32);
                hasher.Update(sk, skoffset + 32, 32);
                hasher.Update(m, moffset, mlen);
                hram = hasher.Finish();

                ScalarOperations.sc_reduce(hram);
                var s = new byte[32];                 // TODO: remove allocation
                Array.Copy(sig, sigoffset + 32, s, 0, 32);
                ScalarOperations.sc_muladd(s, hram, az, r);
                Array.Copy(s, 0, sig, sigoffset + 32, 32);
                CryptoBytes.Wipe(s);
            }
        }
Beispiel #6
0
        /*public static void crypto_sign(
         * byte[] sm, out int smlen,
         * byte[] m, int mlen,
         * byte[] sk
         * )
         * {
         *  byte[] az = new byte[64];
         *  byte[] r = new byte[64];
         *  byte[] hram = new byte[64];
         *  GroupElementP3 R;
         *  int i;
         *
         *  Helpers.crypto_hash_sha512(az, sk, 0, 32);
         *  az[0] &= 248;
         *  az[31] &= 63;
         *  az[31] |= 64;
         *
         *  smlen = mlen + 64;
         *  for (i = 0; i < mlen; ++i) sm[64 + i] = m[i];
         *  for (i = 0; i < 32; ++i) sm[32 + i] = az[32 + i];
         *  Helpers.crypto_hash_sha512(r, sm, 32, mlen + 32);
         *  for (i = 0; i < 32; ++i) sm[32 + i] = sk[32 + i];
         *
         *  ScalarOperations.sc_reduce(r);
         *  GroupOperations.ge_scalarmult_base(out R, r, 0);
         *  GroupOperations.ge_p3_tobytes(sm, 0, ref R);
         *
         *  Helpers.crypto_hash_sha512(hram, sm, 0, mlen + 64);
         *  ScalarOperations.sc_reduce(hram);
         *  var sm32 = new byte[32];
         *  Array.Copy(sm, 32, sm32, 0, 32);
         *  ScalarOperations.sc_muladd(sm32, hram, az, r);
         *  Array.Copy(sm32, 0, sm, 32, 32);
         * }*/

        public static void crypto_sign2(
            byte[] sig, int sigoffset,
            byte[] m, int moffset, int mlen,
            byte[] sk, int skoffset)
        {
            var hasher = new Sha512();
            {
                hasher.Update(sk, skoffset, 32);
                var az = hasher.Finish();
                stellar_dotnet_sdk.chaos.nacl.Internal.Ed25519Ref10.ScalarOperations.ScClamp(az, 0);

                hasher.Init();
                hasher.Update(az, 32, 32);
                hasher.Update(m, moffset, mlen);
                var r = hasher.Finish();

                stellar_dotnet_sdk.chaos.nacl.Internal.Ed25519Ref10.ScalarOperations.ScReduce(r);
                GroupElementP3 R;
                stellar_dotnet_sdk.chaos.nacl.Internal.Ed25519Ref10.GroupOperations.GeScalarmultBase(out R, r, 0);
                stellar_dotnet_sdk.chaos.nacl.Internal.Ed25519Ref10.GroupOperations.ge_p3_tobytes(sig, sigoffset, ref R);

                hasher.Init();
                hasher.Update(sig, sigoffset, 32);
                hasher.Update(sk, skoffset + 32, 32);
                hasher.Update(m, moffset, mlen);
                var hram = hasher.Finish();

                stellar_dotnet_sdk.chaos.nacl.Internal.Ed25519Ref10.ScalarOperations.ScReduce(hram);
                var s = new byte[32];
                Array.Copy(sig, sigoffset + 32, s, 0, 32);
                stellar_dotnet_sdk.chaos.nacl.Internal.Ed25519Ref10.ScalarOperations.ScMulAdd(s, hram, az, r);
                Array.Copy(s, 0, sig, sigoffset + 32, 32);
                CryptoBytes.Wipe(s);
            }
        }
Beispiel #7
0
        public static void CryptoSign(
            byte[] sig, int sigoffset,
            byte[] m, int moffset, int mlen,
            byte[] sk, int skoffset)
        {
            var hasher = new Sha512();
            {
                hasher.Update(sk, skoffset, 32);
                var az = hasher.Finalize();
                ScalarOperations.Clamp(az, 0);

                hasher.Init();
                hasher.Update(az, 32, 32);
                hasher.Update(m, moffset, mlen);
                var r = hasher.Finalize();

                ScalarOperations.Reduce(r);
                GroupElementP3 R;
                GroupOperations.ScalarMultBase(out R, r, 0);
                GroupOperations.P3ToBytes(sig, sigoffset, ref R);

                hasher.Init();
                hasher.Update(sig, sigoffset, 32);
                hasher.Update(sk, skoffset + 32, 32);
                hasher.Update(m, moffset, mlen);
                var hram = hasher.Finalize();

                ScalarOperations.Reduce(hram);
                var s = new byte[32];
                Array.Copy(sig, sigoffset + 32, s, 0, 32);
                ScalarOperations.MulAdd(s, hram, az, r);
                Array.Copy(s, 0, sig, sigoffset + 32, 32);
                CryptoBytes.Wipe(s);
            }
        }
        public static void crypto_sign_keypair(byte[] pk, int pkoffset, byte[] sk, int skoffset, byte[] seed, int seedoffset)
        {
            GroupElementP3 A;
            int            i;

            Array.Copy(seed, seedoffset, sk, skoffset, 32);

            var blake2bConfig = new Blake2BConfig
            {
                OutputSizeInBytes = 64
            };
            var hasher = Blake2B.Create(blake2bConfig);

            hasher.Update(sk, skoffset, 32);
            byte[] h = hasher.Finish();
            //byte[] h = Sha512.Hash(sk, skoffset, 32);//ToDo: Remove alloc
            ScalarOperations.sc_clamp(h, 0);

            GroupOperations.ge_scalarmult_base(out A, h, 0);
            GroupOperations.ge_p3_tobytes(pk, pkoffset, ref A);

            for (i = 0; i < 32; ++i)
            {
                sk[skoffset + 32 + i] = pk[pkoffset + i];
            }
            CryptoBytes.Wipe(h);
        }
Beispiel #9
0
        public void WipeSegment()
        {
            var bytes      = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
            var wipedBytes = new byte[] { 1, 2, 0, 0, 0, 0, 0, 8, 9, 10 };

            CryptoBytes.Wipe(new ArraySegment <byte>(bytes, 2, 5));
            TestHelpers.AssertEqualBytes(wipedBytes, bytes);
        }
Beispiel #10
0
 public static byte[] ExpandedPrivateKeyFromSeed(byte[] privateKeySeed)
 {
     byte[] privateKey;
     byte[] publicKey;
     KeyPairFromSeed(out publicKey, out privateKey, privateKeySeed);
     CryptoBytes.Wipe(publicKey);
     return(privateKey);
 }
Beispiel #11
0
        public void WipeInterval()
        {
            var bytes      = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
            var wipedBytes = new byte[] { 1, 2, 0, 0, 0, 0, 0, 8, 9, 10 };

            CryptoBytes.Wipe(bytes, 2, 5);
            TestHelpers.AssertEqualBytes(wipedBytes, bytes);
        }
Beispiel #12
0
        /// <summary>
        /// Signs the transaction.
        /// </summary>
        /// <param name="keyPair">The key pair.</param>
        /// <param name="payload">The payload.</param>
        /// <returns>The signature.</returns>
        internal static byte[] SignTransaction(KeyPair keyPair, byte[] payload)
        {
            var sig = new byte[64];
            var sk  = new byte[64];

            Array.Copy(keyPair.PrivateKey, sk, 32);
            Array.Copy(keyPair.PublicKey, 0, sk, 32, 32);
            Ed25519.crypto_sign2(sig, payload, sk, 32);
            CryptoBytes.Wipe(sk);

            return(sig);
        }
        // Original crypto_sign_open, for reference only

        /*public static int crypto_sign_open(
         * byte[] m, out int mlen,
         * byte[] sm, int smlen,
         * byte[] pk)
         * {
         *  byte[] h = new byte[64];
         *  byte[] checkr = new byte[32];
         *  GroupElementP3 A;
         *  GroupElementP2 R;
         *  int i;
         *
         *  mlen = -1;
         *  if (smlen < 64) return -1;
         *  if ((sm[63] & 224) != 0) return -1;
         *  if (GroupOperations.ge_frombytes_negate_vartime(out A, pk, 0) != 0) return -1;
         *
         *  for (i = 0; i < smlen; ++i) m[i] = sm[i];
         *  for (i = 0; i < 32; ++i) m[32 + i] = pk[i];
         *  Sha512BclWrapper.crypto_hash_sha512(h, m, 0, smlen);
         *  ScalarOperations.sc_reduce(h);
         *
         *  var sm32 = new byte[32];
         *  Array.Copy(sm, 32, sm32, 0, 32);
         *  GroupOperations.ge_double_scalarmult_vartime(out R, h, ref A, sm32);
         *  GroupOperations.ge_tobytes(checkr, 0, ref R);
         *  if (Helpers.crypto_verify_32(checkr, sm) != 0)
         *  {
         *      for (i = 0; i < smlen; ++i)
         *          m[i] = 0;
         *      return -1;
         *  }
         *
         *  for (i = 0; i < smlen - 64; ++i)
         *      m[i] = sm[64 + i];
         *  for (i = smlen - 64; i < smlen; ++i)
         *      m[i] = 0;
         *  mlen = smlen - 64;
         *  return 0;
         * }*/

        public static bool crypto_sign_verify(
            byte[] sig, int sigoffset,
            byte[] m, int moffset, int mlen,
            byte[] pk, int pkoffset)
        {
            byte[]         h;
            byte[]         checkr = new byte[32];
            GroupElementP3 A;
            GroupElementP2 R;

            if ((sig[sigoffset + 63] & 224) != 0)
            {
                return(false);
            }
            if (GroupOperations.ge_frombytes_negate_vartime(out A, pk, pkoffset) != 0)
            {
                return(false);
            }

            var blake2bConfig = new Blake2BConfig
            {
                OutputSizeInBytes = 64
            };
            var hasher = Blake2B.Create(blake2bConfig);

            hasher.Update(sig, sigoffset, 32);
            hasher.Update(pk, pkoffset, 32);
            hasher.Update(m, moffset, mlen);
            h = hasher.Finish();

            /*
             * var hasher = new Sha512();
             * hasher.Update(sig, sigoffset, 32);
             * hasher.Update(pk, pkoffset, 32);
             * hasher.Update(m, moffset, mlen);
             * h = hasher.Finish();
             */

            ScalarOperations.sc_reduce(h);

            var sm32 = new byte[32];//todo: remove allocation

            Array.Copy(sig, sigoffset + 32, sm32, 0, 32);
            GroupOperations.ge_double_scalarmult_vartime(out R, h, ref A, sm32);
            GroupOperations.ge_tobytes(checkr, 0, ref R);
            var result = CryptoBytes.ConstantTimeEquals(checkr, 0, sig, sigoffset, 32);

            CryptoBytes.Wipe(h);
            CryptoBytes.Wipe(checkr);
            return(result);
        }
Beispiel #14
0
        /// <summary>
        /// Signs the specified data with this keypair.
        /// </summary>
        /// <param name="data">The data.</param>
        /// <returns>System.Byte[].</returns>
        /// <exception cref="ArgumentNullException">data</exception>
        public byte[] Sign(byte[] data)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }
            var sig = new byte[64];
            var sk  = new byte[64];

            Array.Copy(PrivateKey, sk, 32);
            Array.Copy(PublicKey, 0, sk, 32, 32);
            Ed25519.crypto_sign2(sig, data, sk, 32);
            CryptoBytes.Wipe(sk);
            return(sig);
        }
Beispiel #15
0
        public static void crypto_sign_keypair(byte[] pk, int pkoffset, byte[] sk, int skoffset, byte[] seed, int seedoffset)
        {
            GroupElementP3 A;
            int            i;

            Array.Copy(seed, seedoffset, sk, skoffset, 32);
            byte[] h = Sha512.Hash(sk, skoffset, 32);//ToDo: Remove alloc
            ScalarOperations.sc_clamp(h, 0);

            GroupOperations.ge_scalarmult_base(out A, h, 0);
            GroupOperations.ge_p3_tobytes(pk, pkoffset, ref A);

            for (i = 0; i < 32; ++i)
            {
                sk[skoffset + 32 + i] = pk[pkoffset + i];
            }
            CryptoBytes.Wipe(h);
        }
Beispiel #16
0
        public static void CryptoSignKeypair(byte[] pk, int pkoffset, byte[] sk, int skoffset, byte[] seed,
                                             int seedoffset)
        {
            int i;

            Array.Copy(seed, seedoffset, sk, skoffset, 32);
            var h = Sha512.Hash(sk, skoffset, 32); //ToDo: Remove alloc

            ScalarOperations.ScClamp(h, 0);

            stellar_dotnet_sdk.chaos.nacl.Internal.Ed25519Ref10.GroupOperations.GeScalarmultBase(out var a, h, 0);
            stellar_dotnet_sdk.chaos.nacl.Internal.Ed25519Ref10.GroupOperations.ge_p3_tobytes(pk, pkoffset, ref a);

            for (i = 0; i < 32; ++i)
            {
                sk[skoffset + 32 + i] = pk[pkoffset + i];
            }
            CryptoBytes.Wipe(h);
        }
Beispiel #17
0
        public static void CryptoSignKeyPair(byte[] pk, int pkoffset, byte[] sk, int skoffset, byte[] seed,
                                             int seedoffset)
        {
            int i;

            Array.Copy(seed, seedoffset, sk, skoffset, 32);
            var h = Sha512.Hash(sk, skoffset, 32);

            ScalarOperations.Clamp(h, 0);

            GroupOperations.ScalarMultBase(out var A, h, 0);
            GroupOperations.P3ToBytes(pk, pkoffset, ref A);

            for (i = 0; i < 32; ++i)
            {
                sk[skoffset + 32 + i] = pk[pkoffset + i];
            }
            CryptoBytes.Wipe(h);
        }
        /*public static void crypto_sign(
         * byte[] sm, out int smlen,
         * byte[] m, int mlen,
         * byte[] sk
         * )
         * {
         *      byte[] az = new byte[64];
         *      byte[] r = new byte[64];
         *      byte[] hram = new byte[64];
         *      GroupElementP3 R;
         *      int i;
         *
         *      Helpers.crypto_hash_sha512(az, sk, 0, 32);
         *      az[0] &= 248;
         *      az[31] &= 63;
         *      az[31] |= 64;
         *
         *      smlen = mlen + 64;
         *      for (i = 0; i < mlen; ++i) sm[64 + i] = m[i];
         *      for (i = 0; i < 32; ++i) sm[32 + i] = az[32 + i];
         *      Helpers.crypto_hash_sha512(r, sm, 32, mlen + 32);
         *      for (i = 0; i < 32; ++i) sm[32 + i] = sk[32 + i];
         *
         *      ScalarOperations.sc_reduce(r);
         *      GroupOperations.ge_scalarmult_base(out R, r, 0);
         *      GroupOperations.ge_p3_tobytes(sm, 0, ref R);
         *
         *      Helpers.crypto_hash_sha512(hram, sm, 0, mlen + 64);
         *      ScalarOperations.sc_reduce(hram);
         *      var sm32 = new byte[32];
         *      Array.Copy(sm, 32, sm32, 0, 32);
         *      ScalarOperations.sc_muladd(sm32, hram, az, r);
         *      Array.Copy(sm32, 0, sm, 32, 32);
         * }*/

        public static void crypto_sign2(
            byte[] sig, int sigoffset,
            byte[] m, int moffset, int mlen,
            byte[] sk, int skoffset)
        {
            byte[]         az;
            byte[]         r;
            byte[]         hram;
            GroupElementP3 R;
            var            blake2bConfig = new Blake2BConfig
            {
                OutputSizeInBytes = 64
            };
            var hasher = Blake2B.Create(blake2bConfig);
            //var hasher = new Sha512();
            {
                hasher.Update(sk, skoffset, 32);
                az = hasher.Finish();
                ScalarOperations.sc_clamp(az, 0);

                hasher.Init();
                hasher.Update(az, 32, 32);
                hasher.Update(m, moffset, mlen);
                r = hasher.Finish();

                ScalarOperations.sc_reduce(r);
                GroupOperations.ge_scalarmult_base(out R, r, 0);
                GroupOperations.ge_p3_tobytes(sig, sigoffset, ref R);

                hasher.Init();
                hasher.Update(sig, sigoffset, 32);
                hasher.Update(sk, skoffset + 32, 32);
                hasher.Update(m, moffset, mlen);
                hram = hasher.Finish();

                ScalarOperations.sc_reduce(hram);
                var s = new byte[32];                //todo: remove allocation
                Array.Copy(sig, sigoffset + 32, s, 0, 32);
                ScalarOperations.sc_muladd(s, hram, az, r);
                Array.Copy(s, 0, sig, sigoffset + 32, 32);
                CryptoBytes.Wipe(s);
            }
        }
Beispiel #19
0
        public static void CryptoSignKeypair(byte[] pk, int pkoffset, byte[] sk, int skoffset, byte[] seed,
                                             int seedoffset)
        {
            int i;

            Array.Copy(seed, seedoffset, sk, skoffset, 32);
            byte[] h = Sha512.Hash(sk, skoffset, 32); //ToDo: Remove alloc
            ScalarOperations.ScClamp(h, 0);

            GroupOperations.GeScalarmultBase(out GroupElementP3 a, h, 0);
            GroupOperations.ge_p3_tobytes(pk, pkoffset, ref a);

            for (i = 0; i < 32; ++i)
            {
                sk[skoffset + 32 + i] = pk[pkoffset + i];
            }

            CryptoBytes.Wipe(h);
        }
Beispiel #20
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Signature"/> class.
        /// </summary>
        /// <remarks>
        /// Uses twisted edwards elliptic curve, Ed25519, to produce signatures.
        /// </remarks>
        /// <param name="data">The data bytes to sign.</param>
        /// <param name="privateKey">The private key used to sign the bytes.</param>
        /// <example>
        /// This sample shows how to create a new instance of the <see cref="Signature"/> class and produce a signature.
        /// <code>
        /// class TestClass
        /// {
        ///     static void Main()
        ///     {
        ///         byte[] bytes = new byte[10];
        ///
        ///         Signature sig = new Signature(bytes, new PrivateKey("0705c2634de7e58325dabc58c4a794559be4d55d102d3aafcb189acb2e596add"));
        ///
        ///         string signature = sig._Signature;
        ///     }
        /// }
        /// </code>
        /// </example>
        public Signature(byte[] data, PrivateKey privateKey)
        {
            var sig = new byte[64];

            try
            {
                var sk = new byte[64];
                Array.Copy(CryptoBytes.FromHexString(StringUtils.ConvertToUnsecureString(privateKey.Raw)), sk, 32);
                Array.Copy(
                    CryptoBytes.FromHexString(
                        new PublicKey(PublicKeyConversion.ToPublicKey(privateKey)).Raw), 0,
                    sk, 32, 32);
                Ed25519.crypto_sign2(sig, data, sk, 32);
                CryptoBytes.Wipe(sk);
            }
            finally
            {
                _Signature = sig;
            }
        }
        public static void crypto_sign2(
            byte[] sig, int sigoffset,
            byte[] m, int moffset, int mlen,
            byte[] sk, int skoffset)
        {
            byte[]         az   = new byte[64];
            byte[]         r    = new byte[64];
            byte[]         hram = new byte[64];
            GroupElementP3 R;


            var hasher2 = new Sha3Digest(512);
            {
                hasher2.BlockUpdate(sk, 0, 32);
                hasher2.DoFinal(az, 0);
                ScalarOperations.sc_clamp(az, 0);

                hasher2.Reset();
                hasher2.BlockUpdate(az, 32, 32);
                hasher2.BlockUpdate(m, moffset, mlen);
                hasher2.DoFinal(r, 0);

                ScalarOperations.sc_reduce(r);
                GroupOperations.ge_scalarmult_base(out R, r, 0);
                GroupOperations.ge_p3_tobytes(sig, sigoffset, ref R);

                hasher2.Reset();
                hasher2.BlockUpdate(sig, sigoffset, 32);
                hasher2.BlockUpdate(sk, skoffset + 32, 32);
                hasher2.BlockUpdate(m, moffset, mlen);
                hasher2.DoFinal(hram, 0);

                ScalarOperations.sc_reduce(hram);
                var s = new byte[32];
                Array.Copy(sig, sigoffset + 32, s, 0, 32);
                ScalarOperations.sc_muladd(s, hram, az, r);
                Array.Copy(s, 0, sig, sigoffset + 32, 32);

                CryptoBytes.Wipe(s);
            }
        }
Beispiel #22
0
        // Original crypto_sign_open, for reference only

        /*public static int crypto_sign_open(
         * byte[] m, out int mlen,
         * byte[] sm, int smlen,
         * byte[] pk)
         * {
         *  byte[] h = new byte[64];
         *  byte[] checkr = new byte[32];
         *  GroupElementP3 A;
         *  GroupElementP2 R;
         *  int i;
         *
         *  mlen = -1;
         *  if (smlen < 64) return -1;
         *  if ((sm[63] & 224) != 0) return -1;
         *  if (GroupOperations.ge_frombytes_negate_vartime(out A, pk, 0) != 0) return -1;
         *
         *  for (i = 0; i < smlen; ++i) m[i] = sm[i];
         *  for (i = 0; i < 32; ++i) m[32 + i] = pk[i];
         *  Sha512BclWrapper.crypto_hash_sha512(h, m, 0, smlen);
         *  ScalarOperations.sc_reduce(h);
         *
         *  var sm32 = new byte[32];
         *  Array.Copy(sm, 32, sm32, 0, 32);
         *  GroupOperations.ge_double_scalarmult_vartime(out R, h, ref A, sm32);
         *  GroupOperations.ge_tobytes(checkr, 0, ref R);
         *  if (Helpers.crypto_verify_32(checkr, sm) != 0)
         *  {
         *      for (i = 0; i < smlen; ++i)
         *          m[i] = 0;
         *      return -1;
         *  }
         *
         *  for (i = 0; i < smlen - 64; ++i)
         *      m[i] = sm[64 + i];
         *  for (i = smlen - 64; i < smlen; ++i)
         *      m[i] = 0;
         *  mlen = smlen - 64;
         *  return 0;
         * }*/

        public static bool crypto_sign_verify(
            byte[] sig, int sigoffset,
            byte[] m, int moffset, int mlen,
            byte[] pk, int pkoffset)
        {
            byte[]         checkr = new byte[32];
            GroupElementP3 A;
            GroupElementP2 R;

            if ((sig[sigoffset + 63] & 224) != 0)
            {
                return(false);
            }
            if (GroupOperations.ge_frombytes_negate_vartime(out A, pk, pkoffset) != 0)
            {
                return(false);
            }
            var hash = new KeccakDigest(512);

            hash.BlockUpdate(sig, sigoffset, 32);
            hash.BlockUpdate(pk, pkoffset, 32);
            hash.BlockUpdate(m, moffset, mlen);
            var b = new byte[64];

            hash.DoFinal(b, 0);


            ScalarOperations.sc_reduce(b);

            var sm32 = new byte[32];//todo: remove allocation

            Array.Copy(sig, sigoffset + 32, sm32, 0, 32);
            GroupOperations.ge_double_scalarmult_vartime(out R, b, ref A, sm32);
            GroupOperations.ge_tobytes(checkr, 0, ref R);
            var result = CryptoBytes.ConstantTimeEquals(checkr, 0, sig, sigoffset, 32);

            CryptoBytes.Wipe(b);
            CryptoBytes.Wipe(checkr);
            return(result);
        }
Beispiel #23
0
        internal static void crypto_sign_keypair(byte[] pk, int pkoffset, byte[] sk, int skoffset, byte[] seed, int seedoffset)
        {
            GroupElementP3 A;
            int            i;

            Array.Copy(seed, seedoffset, sk, skoffset, 32);
            var digest = new Sha3Digest(512);     //new  // tried and failed -> new Sha3Digest(512);

            byte[] h = new byte[64];              // byte[] ha = Sha512.Hash(sk, skoffset, 32);//ToDo: Remove alloc
            digest.BlockUpdate(sk, skoffset, 32); // new
            digest.DoFinal(h, 0);                 // new

            ScalarOperations.sc_clamp(h, 0);
            GroupOperations.ge_scalarmult_base(out A, h, 0);
            GroupOperations.ge_p3_tobytes(pk, pkoffset, ref A);

            for (i = 0; i < 32; ++i)
            {
                sk[skoffset + 32 + i] = pk[pkoffset + i];
            }
            CryptoBytes.Wipe(h);
        }
Beispiel #24
0
        /*public static void crypto_sign(
         * byte[] sm, out int smlen,
         * byte[] m, int mlen,
         * byte[] sk
         * )
         * {
         *      byte[] az = new byte[64];
         *      byte[] r = new byte[64];
         *      byte[] hram = new byte[64];
         *      GroupElementP3 R;
         *      int i;
         *
         *      Helpers.crypto_hash_sha512(az, sk, 0, 32);
         *      az[0] &= 248;
         *      az[31] &= 63;
         *      az[31] |= 64;
         *
         *      smlen = mlen + 64;
         *      for (i = 0; i < mlen; ++i) sm[64 + i] = m[i];
         *      for (i = 0; i < 32; ++i) sm[32 + i] = az[32 + i];
         *      Helpers.crypto_hash_sha512(r, sm, 32, mlen + 32);
         *      for (i = 0; i < 32; ++i) sm[32 + i] = sk[32 + i];
         *
         *      ScalarOperations.sc_reduce(r);
         *      GroupOperations.ge_scalarmult_base(out R, r, 0);
         *      GroupOperations.ge_p3_tobytes(sm, 0, ref R);
         *
         *      Helpers.crypto_hash_sha512(hram, sm, 0, mlen + 64);
         *      ScalarOperations.sc_reduce(hram);
         *      var sm32 = new byte[32];
         *      Array.Copy(sm, 32, sm32, 0, 32);
         *      ScalarOperations.sc_muladd(sm32, hram, az, r);
         *      Array.Copy(sm32, 0, sm, 32, 32);
         * }*/

        public static void crypto_sign2(
            byte[] sig, int sigoffset,
            byte[] m, int moffset, int mlen,
            byte[] sk, int skoffset)
        {
            byte[]         az;
            byte[]         r;
            byte[]         hram;
            GroupElementP3 R;
            var            hasher = Blake2Fast.Blake2b.CreateIncrementalHasher(64);
            //var hasher = new Sha512();
            {
                hasher.Update(new ArraySegment <byte>(sk, skoffset, 32));
                az = hasher.Finish();
                ScalarOperations.sc_clamp(az, 0);

                hasher = Blake2Fast.Blake2b.CreateIncrementalHasher(64);
                hasher.Update(new ArraySegment <byte>(az, 32, 32));
                hasher.Update(new ArraySegment <byte>(m, moffset, mlen));
                r = hasher.Finish();

                ScalarOperations.sc_reduce(r);
                GroupOperations.ge_scalarmult_base(out R, r, 0);
                GroupOperations.ge_p3_tobytes(sig, sigoffset, ref R);

                hasher = Blake2Fast.Blake2b.CreateIncrementalHasher(64);
                hasher.Update(new ArraySegment <byte>(sig, sigoffset, 32));
                hasher.Update(new ArraySegment <byte>(sk, skoffset + 32, 32));
                hasher.Update(new ArraySegment <byte>(m, moffset, mlen));
                hram = hasher.Finish();

                ScalarOperations.sc_reduce(hram);
                var s = new byte[32];                //todo: remove allocation
                Array.Copy(sig, sigoffset + 32, s, 0, 32);
                ScalarOperations.sc_muladd(s, hram, az, r);
                Array.Copy(s, 0, sig, sigoffset + 32, 32);
                CryptoBytes.Wipe(s);
            }
        }
        public static bool crypto_sign_verify(
            byte[] signature, int signatureOffset,
            byte[] message, int messageOffset, int messageLength,
            byte[] publicKey, int publicKeyOffset)
        {
            byte[]         h;
            byte[]         checkr = new byte[32];
            GroupElementP3 A;
            GroupElementP2 R;

            if ((signature[signatureOffset + 63] & 224) != 0)
            {
                return(false);
            }
            if (GroupOperations.ge_frombytes_negate_vartime(out A, publicKey, publicKeyOffset) != 0)
            {
                return(false);
            }

            var hasher = new Sha512();

            hasher.Update(signature, signatureOffset, 32);
            hasher.Update(publicKey, publicKeyOffset, 32);
            hasher.Update(message, messageOffset, messageLength);
            h = hasher.FinalizeHash();

            ScalarOperations.sc_reduce(h);

            var sm32 = new byte[32];//todo: remove allocation

            Array.Copy(signature, signatureOffset + 32, sm32, 0, 32);
            GroupOperations.ge_double_scalarmult_vartime(out R, h, ref A, sm32);
            GroupOperations.ge_tobytes(checkr, 0, ref R);
            var result = CryptoBytes.ConstantTimeEquals(checkr, 0, signature, signatureOffset, 32);

            CryptoBytes.Wipe(h);
            CryptoBytes.Wipe(checkr);
            return(result);
        }
Beispiel #26
0
        public static bool CryptoSignVerify(
            byte[] sig, int sigoffset,
            byte[] m, int moffset, int mlen,
            byte[] pk, int pkoffset)
        {
            var            checker = new byte[32];
            GroupElementP3 A;
            GroupElementP2 R;

            if ((sig[sigoffset + 63] & 224) != 0)
            {
                return(false);
            }
            if (GroupOperations.FromBytes(out A, pk, pkoffset) != 0)
            {
                return(false);
            }

            var hasher = new Sha512();

            hasher.Update(sig, sigoffset, 32);
            hasher.Update(pk, pkoffset, 32);
            hasher.Update(m, moffset, mlen);
            var h = hasher.Finalize();

            ScalarOperations.Reduce(h);

            var sm32 = new byte[32];

            Array.Copy(sig, sigoffset + 32, sm32, 0, 32);
            GroupOperations.DoubleScalarMult(out R, h, ref A, sm32);
            GroupOperations.ToBytes(checker, 0, ref R);
            var result = CryptoBytes.ConstantTimeEquals(checker, 0, sig, sigoffset, 32);

            CryptoBytes.Wipe(h);
            CryptoBytes.Wipe(checker);
            return(result);
        }
Beispiel #27
0
        // Original crypto_sign_open, for reference only

        /*public static int crypto_sign_open(
         * byte[] m, out int mlen,
         * byte[] sm, int smlen,
         * byte[] pk)
         * {
         *  byte[] h = new byte[64];
         *  byte[] checkr = new byte[32];
         *  GroupElementP3 A;
         *  GroupElementP2 R;
         *  int i;
         *
         *  mlen = -1;
         *  if (smlen < 64) return -1;
         *  if ((sm[63] & 224) != 0) return -1;
         *  if (GroupOperations.ge_frombytes_negate_vartime(out A, pk, 0) != 0) return -1;
         *
         *  for (i = 0; i < smlen; ++i) m[i] = sm[i];
         *  for (i = 0; i < 32; ++i) m[32 + i] = pk[i];
         *  Sha512BclWrapper.crypto_hash_sha512(h, m, 0, smlen);
         *  ScalarOperations.sc_reduce(h);
         *
         *  var sm32 = new byte[32];
         *  Array.Copy(sm, 32, sm32, 0, 32);
         *  GroupOperations.ge_double_scalarmult_vartime(out R, h, ref A, sm32);
         *  GroupOperations.ge_tobytes(checkr, 0, ref R);
         *  if (Helpers.crypto_verify_32(checkr, sm) != 0)
         *  {
         *      for (i = 0; i < smlen; ++i)
         *          m[i] = 0;
         *      return -1;
         *  }
         *
         *  for (i = 0; i < smlen - 64; ++i)
         *      m[i] = sm[64 + i];
         *  for (i = smlen - 64; i < smlen; ++i)
         *      m[i] = 0;
         *  mlen = smlen - 64;
         *  return 0;
         * }*/

        public static bool CryptoSignVerify(
            byte[] sig, int sigoffset,
            byte[] m, int moffset, int mlen,
            byte[] pk, int pkoffset)
        {
            var            checkr = new byte[32];
            GroupElementP3 A;
            GroupElementP2 R;

            if ((sig[sigoffset + 63] & 224) != 0)
            {
                return(false);
            }
            if (stellar_dotnet_sdk.chaos.nacl.Internal.Ed25519Ref10.GroupOperations.ge_frombytes_negate_vartime(out A, pk, pkoffset) != 0)
            {
                return(false);
            }

            var hasher = new Sha512();

            hasher.Update(sig, sigoffset, 32);
            hasher.Update(pk, pkoffset, 32);
            hasher.Update(m, moffset, mlen);
            var h = hasher.Finish();

            ScalarOperations.ScReduce(h);

            var sm32 = new byte[32]; //todo: remove allocation

            Array.Copy(sig, sigoffset + 32, sm32, 0, 32);
            stellar_dotnet_sdk.chaos.nacl.Internal.Ed25519Ref10.GroupOperations.ge_double_scalarmult_vartime(out R, h, ref A, sm32);
            stellar_dotnet_sdk.chaos.nacl.Internal.Ed25519Ref10.GroupOperations.GeToBytes(checkr, 0, ref R);
            var result = CryptoBytes.ConstantTimeEquals(checkr, 0, sig, sigoffset, 32);

            CryptoBytes.Wipe(h);
            CryptoBytes.Wipe(checkr);
            return(result);
        }
Beispiel #28
0
        public static void crypto_sign_keypair(byte[] pk, int pkoffset, byte[] sk, int skoffset, byte[] seed, int seedoffset)
        {
            GroupElementP3 A;
            int            i;

            Array.Copy(seed, seedoffset, sk, skoffset, 32);

            var hasher = Blake2Fast.Blake2b.CreateIncrementalHasher(64);

            hasher.Update(new ArraySegment <byte>(sk, skoffset, 32));
            byte[] h = hasher.Finish();
            //byte[] h = Sha512.Hash(sk, skoffset, 32);//ToDo: Remove alloc
            ScalarOperations.sc_clamp(h, 0);

            GroupOperations.ge_scalarmult_base(out A, h, 0);
            GroupOperations.ge_p3_tobytes(pk, pkoffset, ref A);

            for (i = 0; i < 32; ++i)
            {
                sk[skoffset + 32 + i] = pk[pkoffset + i];
            }
            CryptoBytes.Wipe(h);
        }
Beispiel #29
0
        //[Obsolete("Needs more testing")]
        public static void KeyExchange(ArraySegment <byte> sharedKey, ArraySegment <byte> publicKey, ArraySegment <byte> privateKey)
        {
            if (sharedKey.Array == null)
            {
                throw new ArgumentNullException("sharedKey.Array");
            }
            if (publicKey.Array == null)
            {
                throw new ArgumentNullException("publicKey.Array");
            }
            if (privateKey.Array == null)
            {
                throw new ArgumentNullException("privateKey");
            }
            if (sharedKey.Count != 32)
            {
                throw new ArgumentException("sharedKey.Count != 32");
            }
            if (publicKey.Count != 32)
            {
                throw new ArgumentException("publicKey.Count != 32");
            }
            if (privateKey.Count != 64)
            {
                throw new ArgumentException("privateKey.Count != 64");
            }

            FieldOperations.fe_frombytes(out FieldElement edwardsY, publicKey.Array, publicKey.Offset);
            FieldOperations.fe_1(out FieldElement edwardsZ);
            MontgomeryCurve25519.EdwardsToMontgomeryX(out FieldElement montgomeryX, ref edwardsY, ref edwardsZ);
            byte[] h = Sha512.Hash(privateKey.Array, privateKey.Offset, 32);//ToDo: Remove alloc
            ScalarOperations.sc_clamp(h, 0);
            MontgomeryOperations.scalarmult(out FieldElement sharedMontgomeryX, h, 0, ref montgomeryX);
            CryptoBytes.Wipe(h);
            FieldOperations.fe_tobytes(sharedKey.Array, sharedKey.Offset, ref sharedMontgomeryX);
            MontgomeryCurve25519.KeyExchangeOutputHashNaCl(sharedKey.Array, sharedKey.Offset);
        }
Beispiel #30
0
        /*public static void crypto_sign(
         * byte[] sm, out int smlen,
         * byte[] m, int mlen,
         * byte[] sk
         * )
         * {
         *  byte[] az = new byte[64];
         *  byte[] r = new byte[64];
         *  byte[] hram = new byte[64];
         *  GroupElementP3 R;
         *  int i;
         *
         *  Helpers.crypto_hash_sha512(az, sk, 0, 32);
         *  az[0] &= 248;
         *  az[31] &= 63;
         *  az[31] |= 64;
         *
         *  smlen = mlen + 64;
         *  for (i = 0; i < mlen; ++i) sm[64 + i] = m[i];
         *  for (i = 0; i < 32; ++i) sm[32 + i] = az[32 + i];
         *  Helpers.crypto_hash_sha512(r, sm, 32, mlen + 32);
         *  for (i = 0; i < 32; ++i) sm[32 + i] = sk[32 + i];
         *
         *  ScalarOperations.sc_reduce(r);
         *  GroupOperations.ge_scalarmult_base(out R, r, 0);
         *  GroupOperations.ge_p3_tobytes(sm, 0, ref R);
         *
         *  Helpers.crypto_hash_sha512(hram, sm, 0, mlen + 64);
         *  ScalarOperations.sc_reduce(hram);
         *  var sm32 = new byte[32];
         *  Array.Copy(sm, 32, sm32, 0, 32);
         *  ScalarOperations.sc_muladd(sm32, hram, az, r);
         *  Array.Copy(sm32, 0, sm, 32, 32);
         * }*/

        public static void crypto_sign2(
            byte[] sig, int sigoffset,
            byte[] m, int moffset, int mlen,
            byte[] sk, int skoffset)
        {
            Sha512 hasher = new Sha512();

            {
                hasher.Update(sk, skoffset, 32);
                byte[] az = hasher.Finish();
                ScalarOperations.ScClamp(az, 0);

                hasher.Init();
                hasher.Update(az, 32, 32);
                hasher.Update(m, moffset, mlen);
                byte[] r = hasher.Finish();

                ScalarOperations.ScReduce(r);
                GroupElementP3 R;
                GroupOperations.GeScalarmultBase(out R, r, 0);
                GroupOperations.ge_p3_tobytes(sig, sigoffset, ref R);

                hasher.Init();
                hasher.Update(sig, sigoffset, 32);
                hasher.Update(sk, skoffset + 32, 32);
                hasher.Update(m, moffset, mlen);
                byte[] hram = hasher.Finish();

                ScalarOperations.ScReduce(hram);
                byte[] s = new byte[32];
                Array.Copy(sig, sigoffset + 32, s, 0, 32);
                ScalarOperations.ScMulAdd(s, hram, az, r);
                Array.Copy(s, 0, sig, sigoffset + 32, 32);
                CryptoBytes.Wipe(s);
            }
        }