//CONVERT #include <string.h>
        //CONVERT #include "crypto_sign.h"
        //CONVERT #include "crypto_hash_sha512.h"
        //CONVERT #include "ge.h"
        //CONVERT #include "sc.h"
        //CONVERT #include "zeroize.h"

        /* NEW: Compare to pristine crypto_sign()
         * Uses explicit private key for nonce derivation and as scalar,
         * instead of deriving both from a master key.
         */
        public static int crypto_sign_modified(
            ISha512 sha512provider,
            byte[] sm,
            byte[] m, long mlen,
            byte[] sk, byte[] pk,
            byte[] random
            )
        {
            byte[] nonce = new byte[64];
            byte[] hram  = new byte[64];
            Ge_p3  R     = new Ge_p3();
            int    count = 0;

            Array.Copy(m, 0, sm, 64, (int)mlen);
            Array.Copy(sk, 0, sm, 32, 32);

            /* NEW : add prefix to separate hash uses - see .h */
            sm[0] = (byte)0xFE;
            for (count = 1; count < 32; count++)
            {
                sm[count] = (byte)0xFF;
            }

            /* NEW: add suffix of random data */
            Array.Copy(random, 0, sm, (int)(mlen + 64), 64);

            sha512provider.calculateDigest(nonce, sm, mlen + 128);
            Array.Copy(pk, 0, sm, 32, 32);

            Sc_reduce.sc_reduce(nonce);
            Ge_scalarmult_base.ge_scalarmult_base(R, nonce);
            Ge_p3_tobytes.ge_p3_tobytes(sm, R);

            sha512provider.calculateDigest(hram, sm, mlen + 64);
            Sc_reduce.sc_reduce(hram);
            byte[] S = new byte[32];
            Sc_muladd.sc_muladd(S, hram, sk, nonce); /* NEW: Use privkey directly */
            Array.Copy(S, 0, sm, 32, 32);

            /* Erase any traces of private scalar or
             * nonce left in the stack from sc_muladd */
            //zeroize_stack();
            Zeroize.zeroize(nonce, 64);
            return(0);
        }
Beispiel #2
0
        public static int uxed25519_sign(ISha512 sha512provider,
                                         byte[] signature_out,
                                         byte[] curve25519_privkey,
                                         byte[] msg, int msg_len,
                                         byte[] random)
        {
            // just return -1 as this shouldn't be used
            return(-1);

            byte[] a    = new byte[32];
            byte[] aneg = new byte[32];
            byte[] A    = new byte[32];

            Ge_p3 Bu = new Ge_p3();
            Ge_p3 ed_pubkey_point = new Ge_p3();

            byte[] sigbuf   = new byte[crypto_additions.MAX_MSG_LEN + 160]; /* working buffer */
            byte   sign_bit = 0;

            if (msg_len > crypto_additions.MAX_MSG_LEN)
            {
                //memset(signature_out, 0, 96);
                return(-1);
            }

            /* Convert the Curve25519 privkey to an Ed25519 public key */
            Ge_scalarmult_base.ge_scalarmult_base(ed_pubkey_point, curve25519_privkey);
            Ge_p3_tobytes.ge_p3_tobytes(A, ed_pubkey_point);

            /* Force Edwards sign bit to zero */
            sign_bit = (byte)((A[31] & 0x80) >> 7);
            Array.Copy(curve25519_privkey, 0, a, 0, 32);
            Sc_neg.sc_neg(aneg, a);
            Sc_cmov.sc_cmov(a, aneg, sign_bit);
            A[31] &= 0x7F;

            //Elligator.calculate_Bv_and_V(sha512provider, Bu, signature_out, sigbuf, a, msg, msg_len);

            /* Perform an Ed25519 signature with explicit private key */
            usign_modified.crypto_usign_modified(sha512provider, sigbuf, msg, msg_len, a, A, random, Bu, signature_out /*U*/);
            Array.Copy(sigbuf, 0, signature_out, 32, 64);

            Zeroize.zeroize(a, 32);
            return(0);
        }
Beispiel #3
0
        public static int xed25519_sign(ISha512 sha512provider,
                                        byte[] signature_out,
                                        byte[] curve25519_privkey,
                                        byte[] msg, int msg_len,
                                        byte[] random)
        {
            byte[] a               = new byte[32];
            byte[] A               = new byte[32];
            byte[] aneg            = new byte[32];
            Ge_p3  ed_pubkey_point = new Ge_p3();

            // see link below
            byte[] sigbuf   = new byte[msg_len + 128]; /* working buffer */
            byte   sign_bit = 0;

            // this should be different but whatever
            // https://github.com/WhisperSystems/curve25519-java/commit/2f388f601afdac6a78a19ced2f0629da1ff9800f#diff-6e488e4e28814b3fa524b6781fcaf912R19
            //if (msg_len > crypto_additions.MAX_MSG_LEN)
            //{
            //    //memset(signature_out, 0, 64);
            //    return -1;
            //}

            /* Convert the Curve25519 privkey to an Ed25519 public key */
            Ge_scalarmult_base.ge_scalarmult_base(ed_pubkey_point, curve25519_privkey);
            Ge_p3_tobytes.ge_p3_tobytes(A, ed_pubkey_point);

            /* Force Edwards sign bit to zero */
            sign_bit = (byte)((A[31] & 0x80) >> 7);
            Array.Copy(curve25519_privkey, 0, a, 0, 32);
            Sc_neg.sc_neg(aneg, a);
            Sc_cmov.sc_cmov(a, aneg, sign_bit);
            A[31] &= 0x7F;

            /* Perform an Ed25519 signature with explicit private key */
            sign_modified.crypto_sign_modified(sha512provider, sigbuf, msg, msg_len, a, A, random);
            Array.Copy(sigbuf, 0, signature_out, 0, 64);

            Zeroize.zeroize(a, 32);
            Zeroize.zeroize(aneg, 32);
            return(0);
        }
        public static int crypto_vsign_modified(ISha512 sha512provider,
                                                byte[] sm,
                                                byte[] M, int Mlen,
                                                byte[] a,
                                                byte[] A,
                                                byte[] random,
                                                Ge_p3 Bv,
                                                byte[] V)
        {
            byte[] r     = new byte[64];
            byte[] h     = new byte[64];
            Ge_p3  R     = new Ge_p3();
            Ge_p3  Rv    = new Ge_p3();
            int    count = 0;

            /* r = SHA512(label(3) || a || V || random(64)) */
            sm[0] = 0xFC;
            for (count = 1; count < 32; count++)
            {
                sm[count] = 0xFF;
            }

            Array.Copy(a, 0, sm, 32, 32); /* Use privkey directly for nonce derivation */
            Array.Copy(V, 0, sm, 64, 32);

            Array.Copy(random, 0, sm, 96, 64); /* Add suffix of random data */
            sha512provider.calculateDigest(r, sm, 160);

            Sc_reduce.sc_reduce(r);
            Ge_scalarmult_base.ge_scalarmult_base(R, r);
            Ge_scalarmult.ge_scalarmult(Rv, r, Bv);

            /* h = SHA512(label(4) || A || V || R || Rv || M) */
            sm[0] = 0xFB;
            Array.Copy(A, 0, sm, 32, 32);
            Array.Copy(V, 0, sm, 64, 32);
            byte[] R1 = new byte[32];
            Array.Copy(sm, 96, R1, 0, 32);
            Ge_p3_tobytes.ge_p3_tobytes(R1, R);
            Array.Copy(R1, 0, sm, 96, 32);
            byte[] R2 = new byte[32];
            Array.Copy(sm, 128, R2, 0, 32);
            Ge_p3_tobytes.ge_p3_tobytes(R2, Rv);
            Array.Copy(R2, 0, sm, 128, 32);
            Array.Copy(M, 0, sm, 160, Mlen);

            sha512provider.calculateDigest(h, sm, Mlen + 160);
            Sc_reduce.sc_reduce(h);

            Array.Copy(h, 0, sm, 0, 32);
            byte[] S = new byte[32];
            Array.Copy(sm, 32, S, 0, 32);
            Sc_muladd.sc_muladd(S, h, a, r);
            Array.Copy(S, 0, sm, 32, 32);

            /* Erase any traces of private scalar or
             * nonce left in stack from sc_muladd. */
            //zeroize_stack();
            Zeroize.zeroize(r, 64);
            return(0);
        }