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);
        }
Example #2
0
        public static void crypto_ecdh_keypair(byte[] publicKey, byte[] privateKey)
        {
            ScalarOperations.sc_clamp(privateKey, 0);

            GroupElementP3 A;

            ge_scalarmult_base(out A, privateKey, 0);
            FieldElement publicKeyFE;

            EdwardsToMontgomeryX(out publicKeyFE, ref A.Y, ref A.Z);
            fe_tobytes(publicKey, 0, ref publicKeyFE);
        }
Example #3
0
        /// <summary>
        /// Generates public key from secret.
        /// </summary>
        /// <param name="tmp">Temporary array of 64 bytes.</param>
        /// <remarks>This method is added by @alexanderdna to reduce allocation and redundant code.</remarks>
        public static void crypto_public_key(byte[] secret, int secretOffset, byte[] publicKey, int publicKeyOffset, byte[] tmp)
        {
            var hasher = Blake2Fast.Blake2b.CreateIncrementalHasher(64);

            hasher.Update(new ArraySegment <byte>(secret, secretOffset, 32));
            hasher.Finish(tmp);

            GroupElementP3 A;

            ScalarOperations.sc_clamp(tmp, 0);
            GroupOperations.ge_scalarmult_base(out A, tmp, 0);
            GroupOperations.ge_p3_tobytes(publicKey, publicKeyOffset, ref A);
        }
Example #4
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 \
        // 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);
        }
        public static void crypto_sign_keypair(byte[] pk, int pkoffset, byte[] sk, int skoffset)
        {
            GroupElementP3 A;
            int            i;

            ScalarOperations.sc_clamp(sk, 0);

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

            for (i = 0; i < 32; ++i)
            {
                sk[skoffset + 32 + i] = pk[pkoffset + i];
            }
        }
Example #7
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);
            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);
        }
        /*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);
            }
        }
Example #9
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);
        }
Example #10
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   = new byte[64];
            byte[]         r    = new byte[64];
            byte[]         hram = new byte[64];
            GroupElementP3 R;
            var            DigestSha3 = new KeccakDigest(512);
            {
                DigestSha3.BlockUpdate(sk, skoffset, 32);
                DigestSha3.DoFinal(az, 0);

                ScalarOperations.sc_clamp(az, 0);

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

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

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

                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);
            }
        }
Example #11
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 digest = new KeccakDigest(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);
        }
Example #12
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);
            }
        }
Example #13
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);
        }
Example #14
0
        internal static void scalarmult(
            out FieldElement q,
            byte[] n, int noffset,
            ref FieldElement p)
        {
            byte[]       e = new byte[32];      //ToDo: remove allocation
            UInt32       i;
            FieldElement x1;
            FieldElement x2;
            FieldElement z2;
            FieldElement x3;
            FieldElement z3;
            FieldElement tmp0;
            FieldElement tmp1;
            int          pos;
            UInt32       swap;
            UInt32       b;

            for (i = 0; i < 32; ++i)
            {
                e[i] = n[noffset + i];
            }
            ScalarOperations.sc_clamp(e, 0);
            x1 = p;
            FieldOperations.fe_1(out x2);
            FieldOperations.fe_0(out z2);
            x3 = x1;
            FieldOperations.fe_1(out z3);

            swap = 0;
            for (pos = 254; pos >= 0; --pos)
            {
                b     = (uint)(e[pos / 8] >> (pos & 7));
                b    &= 1;
                swap ^= b;
                FieldOperations.fe_cswap(ref x2, ref x3, swap);
                FieldOperations.fe_cswap(ref z2, ref z3, swap);
                swap = b;
                /* qhasm: fe X2 */

                /* qhasm: fe Z2 */

                /* qhasm: fe X3 */

                /* qhasm: fe Z3 */

                /* qhasm: fe X4 */

                /* qhasm: fe Z4 */

                /* qhasm: fe X5 */

                /* qhasm: fe Z5 */

                /* qhasm: fe A */

                /* qhasm: fe B */

                /* qhasm: fe C */

                /* qhasm: fe D */

                /* qhasm: fe E */

                /* qhasm: fe AA */

                /* qhasm: fe BB */

                /* qhasm: fe DA */

                /* qhasm: fe CB */

                /* qhasm: fe t0 */

                /* qhasm: fe t1 */

                /* qhasm: fe t2 */

                /* qhasm: fe t3 */

                /* qhasm: fe t4 */

                /* qhasm: enter ladder */

                /* qhasm: D = X3-Z3 */
                /* asm 1: fe_sub(>D=fe#5,<X3=fe#3,<Z3=fe#4); */
                /* asm 2: fe_sub(>D=tmp0,<X3=x3,<Z3=z3); */
                FieldOperations.fe_sub(out tmp0, ref x3, ref z3);

                /* qhasm: B = X2-Z2 */
                /* asm 1: fe_sub(>B=fe#6,<X2=fe#1,<Z2=fe#2); */
                /* asm 2: fe_sub(>B=tmp1,<X2=x2,<Z2=z2); */
                FieldOperations.fe_sub(out tmp1, ref x2, ref z2);

                /* qhasm: A = X2+Z2 */
                /* asm 1: fe_add(>A=fe#1,<X2=fe#1,<Z2=fe#2); */
                /* asm 2: fe_add(>A=x2,<X2=x2,<Z2=z2); */
                FieldOperations.fe_add(out x2, ref x2, ref z2);

                /* qhasm: C = X3+Z3 */
                /* asm 1: fe_add(>C=fe#2,<X3=fe#3,<Z3=fe#4); */
                /* asm 2: fe_add(>C=z2,<X3=x3,<Z3=z3); */
                FieldOperations.fe_add(out z2, ref x3, ref z3);

                /* qhasm: DA = D*A */
                /* asm 1: fe_mul(>DA=fe#4,<D=fe#5,<A=fe#1); */
                /* asm 2: fe_mul(>DA=z3,<D=tmp0,<A=x2); */
                FieldOperations.fe_mul(out z3, ref tmp0, ref x2);

                /* qhasm: CB = C*B */
                /* asm 1: fe_mul(>CB=fe#2,<C=fe#2,<B=fe#6); */
                /* asm 2: fe_mul(>CB=z2,<C=z2,<B=tmp1); */
                FieldOperations.fe_mul(out z2, ref z2, ref tmp1);

                /* qhasm: BB = B^2 */
                /* asm 1: fe_sq(>BB=fe#5,<B=fe#6); */
                /* asm 2: fe_sq(>BB=tmp0,<B=tmp1); */
                FieldOperations.fe_sq(out tmp0, ref tmp1);

                /* qhasm: AA = A^2 */
                /* asm 1: fe_sq(>AA=fe#6,<A=fe#1); */
                /* asm 2: fe_sq(>AA=tmp1,<A=x2); */
                FieldOperations.fe_sq(out tmp1, ref x2);

                /* qhasm: t0 = DA+CB */
                /* asm 1: fe_add(>t0=fe#3,<DA=fe#4,<CB=fe#2); */
                /* asm 2: fe_add(>t0=x3,<DA=z3,<CB=z2); */
                FieldOperations.fe_add(out x3, ref z3, ref z2);

                /* qhasm: assign x3 to t0 */

                /* qhasm: t1 = DA-CB */
                /* asm 1: fe_sub(>t1=fe#2,<DA=fe#4,<CB=fe#2); */
                /* asm 2: fe_sub(>t1=z2,<DA=z3,<CB=z2); */
                FieldOperations.fe_sub(out z2, ref z3, ref z2);

                /* qhasm: X4 = AA*BB */
                /* asm 1: fe_mul(>X4=fe#1,<AA=fe#6,<BB=fe#5); */
                /* asm 2: fe_mul(>X4=x2,<AA=tmp1,<BB=tmp0); */
                FieldOperations.fe_mul(out x2, ref tmp1, ref tmp0);

                /* qhasm: E = AA-BB */
                /* asm 1: fe_sub(>E=fe#6,<AA=fe#6,<BB=fe#5); */
                /* asm 2: fe_sub(>E=tmp1,<AA=tmp1,<BB=tmp0); */
                FieldOperations.fe_sub(out tmp1, ref tmp1, ref tmp0);

                /* qhasm: t2 = t1^2 */
                /* asm 1: fe_sq(>t2=fe#2,<t1=fe#2); */
                /* asm 2: fe_sq(>t2=z2,<t1=z2); */
                FieldOperations.fe_sq(out z2, ref z2);

                /* qhasm: t3 = a24*E */
                /* asm 1: fe_mul121666(>t3=fe#4,<E=fe#6); */
                /* asm 2: fe_mul121666(>t3=z3,<E=tmp1); */
                FieldOperations.fe_mul121666(out z3, ref tmp1);

                /* qhasm: X5 = t0^2 */
                /* asm 1: fe_sq(>X5=fe#3,<t0=fe#3); */
                /* asm 2: fe_sq(>X5=x3,<t0=x3); */
                FieldOperations.fe_sq(out x3, ref x3);

                /* qhasm: t4 = BB+t3 */
                /* asm 1: fe_add(>t4=fe#5,<BB=fe#5,<t3=fe#4); */
                /* asm 2: fe_add(>t4=tmp0,<BB=tmp0,<t3=z3); */
                FieldOperations.fe_add(out tmp0, ref tmp0, ref z3);

                /* qhasm: Z5 = X1*t2 */
                /* asm 1: fe_mul(>Z5=fe#4,x1,<t2=fe#2); */
                /* asm 2: fe_mul(>Z5=z3,x1,<t2=z2); */
                FieldOperations.fe_mul(out z3, ref x1, ref z2);

                /* qhasm: Z4 = E*t4 */
                /* asm 1: fe_mul(>Z4=fe#2,<E=fe#6,<t4=fe#5); */
                /* asm 2: fe_mul(>Z4=z2,<E=tmp1,<t4=tmp0); */
                FieldOperations.fe_mul(out z2, ref tmp1, ref tmp0);

                /* qhasm: return */
            }
            FieldOperations.fe_cswap(ref x2, ref x3, swap);
            FieldOperations.fe_cswap(ref z2, ref z3, swap);

            FieldOperations.fe_invert(out z2, ref z2);
            FieldOperations.fe_mul(out x2, ref x2, ref z2);
            q = x2;
            CryptoBytes.Wipe(e);
        }
Example #15
0
 public static void crypto_secret_key_from_seed(byte[] sk, int skoffset, byte[] seed, int seedoffset)
 {
     byte[] h = Sha512.Hash(seed, seedoffset, 32);            //ToDo: Remove alloc
     ScalarOperations.sc_clamp(h, 0);
     Array.Copy(h, 0, sk, skoffset, 32);
 }
Example #16
0
        public static bool Elligator(byte[] representative, int representativeOffset, byte[] privateKey, int privatekeyOffset)
        {
            GroupElementP3 AA;

            //byte[] h = Sha512.Hash(privateKey, privatekeyOffset, 32);//ToDo: Remove alloc
            ScalarOperations.sc_clamp(privateKey, privatekeyOffset);

            ge_scalarmult_base(out AA, privateKey, privatekeyOffset);

            FieldElement inv1;

            fe_sub(out inv1, ref AA.Z, ref AA.Y); /* edwards25519.FeSub(&inv1, &A.Z, &A.Y) */
            fe_mul(out inv1, ref inv1, ref AA.X); /* edwards25519.FeMul(&inv1, &inv1, &A.X) */
            fe_invert(out inv1, ref inv1);        /* edwards25519.FeInvert(&inv1, &inv1) */

            FieldElement t0, u;

            fe_mul(out u, ref inv1, ref AA.X);  /* edwards25519.FeMul(&u, &inv1, &A.X) */
            fe_add(out t0, ref AA.Y, ref AA.Z); /* edwards25519.FeAdd(&t0, &A.Y, &A.Z) */
            fe_mul(out u, ref u, ref t0);       /* edwards25519.FeMul(&u, &u, &t0) */

            FieldElement v;

            fe_mul(out v, ref t0, ref inv1);      /* edwards25519.FeMul(&v, &t0, &inv1) */
            fe_mul(out v, ref v, ref AA.Z);       /* edwards25519.FeMul(&v, &v, &A.Z) */
            fe_mul(out v, ref v, ref sqrtMinusA); /* edwards25519.FeMul(&v, &v, &sqrtMinusA) */

            FieldElement b;

            fe_add(out b, ref u, ref A);        /* edwards25519.FeAdd(&b, &u, &edwards25519.A) */

            FieldElement c, b3, b8;

            fe_sq(out b3, ref b);          /* edwards25519.FeSquare(&b3, &b) // 2 */
            fe_mul(out b3, ref b3, ref b); /* edwards25519.FeMul(&b3, &b3, &b) // 3 */
            fe_sq(out c, ref b3);          /* edwards25519.FeSquare(&c, &b3) // 6 */
            fe_mul(out c, ref c, ref b);   /* edwards25519.FeMul(&c, &c, &b) // 7 */
            fe_mul(out b8, ref c, ref b);  /* edwards25519.FeMul(&b8, &c, &b) // 8 */
            fe_mul(out c, ref c, ref u);   /* edwards25519.FeMul(&c, &c, &u) */
            q58(out c, ref c);             /* q58(&c, &c) */

            FieldElement chi;

            fe_sq(out chi, ref c);            /* edwards25519.FeSquare(&chi, &c) */
            fe_sq(out chi, ref chi);          /* edwards25519.FeSquare(&chi, &chi) */

            fe_sq(out t0, ref u);             /* edwards25519.FeSquare(&t0, &u) */
            fe_mul(out chi, ref chi, ref t0); /* edwards25519.FeMul(&chi, &chi, &t0) */

            fe_sq(out t0, ref b);             /* edwards25519.FeSquare(&t0, &b) // 2 */
            fe_mul(out t0, ref t0, ref b);    /* edwards25519.FeMul(&t0, &t0, &b) // 3 */
            fe_sq(out t0, ref t0);            /* edwards25519.FeSquare(&t0, &t0) // 6 */
            fe_mul(out t0, ref t0, ref b);    /* edwards25519.FeMul(&t0, &t0, &b) // 7 */
            fe_sq(out t0, ref t0);            /* edwards25519.FeSquare(&t0, &t0) // 14 */
            fe_mul(out chi, ref chi, ref t0); /* edwards25519.FeMul(&chi, &chi, &t0) */
            fe_neg(out chi, ref chi);         /* edwards25519.FeNeg(&chi, &chi) */

            var chiBytes = new byte[32];

            fe_tobytes(chiBytes, 0, ref chi);  /*edwards25519.FeToBytes(&chiBytes, &chi) */
                                               // chi[1] is either 0 or 0xff
            if (chiBytes[1] == 0xff)
            {
                return(false);
            }

            // Calculate r1 = sqrt(-u/(2*(u+A)))
            FieldElement r1;

            fe_mul(out r1, ref c, ref u);              /* edwards25519.FeMul(&r1, &c, &u) */
            fe_mul(out r1, ref r1, ref b3);            /* edwards25519.FeMul(&r1, &r1, &b3) */
            fe_mul(out r1, ref r1, ref sqrtMinusHalf); /* edwards25519.FeMul(&r1, &r1, &sqrtMinusHalf) */

            FieldElement maybeSqrtM1;

            fe_sq(out t0, ref r1);                                      /* edwards25519.FeSquare(&t0, &r1) */
            fe_mul(out t0, ref t0, ref b);                              /* edwards25519.FeMul(&t0, &t0, &b) */
            fe_add(out t0, ref t0, ref t0);                             /* edwards25519.FeAdd(&t0, &t0, &t0) */
            fe_add(out t0, ref t0, ref u);                              /* edwards25519.FeAdd(&t0, &t0, &u) */

            fe_1(out maybeSqrtM1);                                      /* edwards25519.FeOne(&maybeSqrtM1) */
            fe_cmov(ref maybeSqrtM1, ref sqrtm1, fe_isnonzero(ref t0)); /* edwards25519.FeCMove(&maybeSqrtM1, &edwards25519.SqrtM1, edwards25519.FeIsNonZero(&t0)) */
            fe_mul(out r1, ref r1, ref maybeSqrtM1);                    /* edwards25519.FeMul(&r1, &r1, &maybeSqrtM1) */

            // Calculate r = sqrt(-(u+A)/(2u))
            FieldElement r;

            fe_sq(out t0, ref c);                                       /* edwards25519.FeSquare(&t0, &c) // 2 */
            fe_mul(out t0, ref t0, ref c);                              /* edwards25519.FeMul(&t0, &t0, &c) // 3 */
            fe_sq(out t0, ref t0);                                      /* edwards25519.FeSquare(&t0, &t0) // 6 */
            fe_mul(out r, ref t0, ref c);                               /* edwards25519.FeMul(&r, &t0, &c) // 7 */

            fe_sq(out t0, ref u);                                       /* edwards25519.FeSquare(&t0, &u) // 2 */
            fe_mul(out t0, ref t0, ref u);                              /* edwards25519.FeMul(&t0, &t0, &u) // 3 */
            fe_mul(out r, ref r, ref t0);                               /* edwards25519.FeMul(&r, &r, &t0) */

            fe_sq(out t0, ref b8);                                      /* edwards25519.FeSquare(&t0, &b8) // 16 */
            fe_mul(out t0, ref t0, ref b8);                             /* edwards25519.FeMul(&t0, &t0, &b8) // 24 */
            fe_mul(out t0, ref t0, ref b);                              /* edwards25519.FeMul(&t0, &t0, &b) // 25 */
            fe_mul(out r, ref r, ref t0);                               /* edwards25519.FeMul(&r, &r, &t0) */
            fe_mul(out r, ref r, ref sqrtMinusHalf);                    /* edwards25519.FeMul(&r, &r, &sqrtMinusHalf) */

            fe_sq(out t0, ref r);                                       /* edwards25519.FeSquare(&t0, &r) */
            fe_mul(out t0, ref t0, ref u);                              /* edwards25519.FeMul(&t0, &t0, &u) */
            fe_add(out t0, ref t0, ref t0);                             /* edwards25519.FeAdd(&t0, &t0, &t0) */
            fe_add(out t0, ref t0, ref b);                              /* edwards25519.FeAdd(&t0, &t0, &b) */
            fe_1(out maybeSqrtM1);                                      /* edwards25519.FeOne(&maybeSqrtM1) */
            fe_cmov(ref maybeSqrtM1, ref sqrtm1, fe_isnonzero(ref t0)); /* edwards25519.FeCMove(&maybeSqrtM1, &edwards25519.SqrtM1, edwards25519.FeIsNonZero(&t0)) */
            fe_mul(out r, ref r, ref maybeSqrtM1);                      /* edwards25519.FeMul(&r, &r, &maybeSqrtM1) */

            var vBytes = new byte[32];

            fe_tobytes(vBytes, 0, ref v);                                          /* edwards25519.FeToBytes(&vBytes, &v) */
            var vInSquareRootImage = fe_bytesLE(ref vBytes, ref halfQMinus1Bytes); /* vInSquareRootImage := feBytesLE(&vBytes, &halfQMinus1Bytes) */

            fe_cmov(ref r, ref r1, vInSquareRootImage);                            /* edwards25519.FeCMove(&r, &r1, vInSquareRootImage) */

            var pub = new byte[32];

            fe_tobytes(pub, 0, ref u);
            fe_tobytes(representative, representativeOffset, ref r);  /* edwards25519.FeToBytes(representative, &r) */
            return(true);
        }