Beispiel #1
0
        internal static int horst_verify(HashFunctions hs, byte[] pk, byte[] sig, int sigOff, byte[] masks, byte[] m_hash)
        {
            byte[] buffer = new byte[32 * HASH_BYTES];

            uint idx;
            int  i, j, k;

            int sigOffset = sigOff + 64 * HASH_BYTES;

            for (i = 0; i < HORST_K; i++)
            {
                idx = (uint)((m_hash[2 * i] & 0xff) + ((m_hash[2 * i + 1] & 0xff) << 8));

                if ((idx & 1) == 0)
                {
                    hs.hash_n_n(buffer, 0, sig, sigOffset);
                    for (k = 0; k < HASH_BYTES; k++)
                    {
                        buffer[HASH_BYTES + k] = sig[sigOffset + HORST_SKBYTES + k];
                    }
                }
                else
                {
                    hs.hash_n_n(buffer, HASH_BYTES, sig, sigOffset);
                    for (k = 0; k < HASH_BYTES; k++)
                    {
                        buffer[k] = sig[sigOffset + HORST_SKBYTES + k];
                    }
                }
                sigOffset += HORST_SKBYTES + HASH_BYTES;

                for (j = 1; j < HORST_LOGT - 6; j++)
                {
                    idx = idx >> 1; // parent node

                    if ((idx & 1) == 0)
                    {
                        hs.hash_2n_n_mask(buffer, 0, buffer, 0, masks, 2 * (j - 1) * HASH_BYTES);
                        for (k = 0; k < HASH_BYTES; k++)
                        {
                            buffer[HASH_BYTES + k] = sig[sigOffset + k];
                        }
                    }
                    else
                    {
                        hs.hash_2n_n_mask(buffer, HASH_BYTES, buffer, 0, masks, 2 * (j - 1) * HASH_BYTES);
                        for (k = 0; k < HASH_BYTES; k++)
                        {
                            buffer[k] = sig[sigOffset + k];
                        }
                    }
                    sigOffset += HASH_BYTES;
                }

                idx = idx >> 1; // parent node
                hs.hash_2n_n_mask(buffer, 0, buffer, 0, masks, 2 * (HORST_LOGT - 7) * HASH_BYTES);

                for (k = 0; k < HASH_BYTES; k++)
                {
                    if (sig[sigOff + idx * HASH_BYTES + k] != buffer[k])
                    {
                        for (k = 0; k < HASH_BYTES; k++)
                        {
                            pk[k] = 0;
                        }
                        return(-1);
                    }
                }
            }

            // Compute root from level10
            for (j = 0; j < 32; j++)
            {
                hs.hash_2n_n_mask(buffer, j * HASH_BYTES, sig, sigOff + 2 * j * HASH_BYTES, masks, 2 * (HORST_LOGT - 6) * HASH_BYTES);
            }
            // Hash from level 11 to 12
            for (j = 0; j < 16; j++)
            {
                hs.hash_2n_n_mask(buffer, j * HASH_BYTES, buffer, 2 * j * HASH_BYTES, masks, 2 * (HORST_LOGT - 5) * HASH_BYTES);
            }
            // Hash from level 12 to 13
            for (j = 0; j < 8; j++)
            {
                hs.hash_2n_n_mask(buffer, j * HASH_BYTES, buffer, 2 * j * HASH_BYTES, masks, 2 * (HORST_LOGT - 4) * HASH_BYTES);
            }
            // Hash from level 13 to 14
            for (j = 0; j < 4; j++)
            {
                hs.hash_2n_n_mask(buffer, j * HASH_BYTES, buffer, 2 * j * HASH_BYTES, masks, 2 * (HORST_LOGT - 3) * HASH_BYTES);
            }
            // Hash from level 14 to 15
            for (j = 0; j < 2; j++)
            {
                hs.hash_2n_n_mask(buffer, j * HASH_BYTES, buffer, 2 * j * HASH_BYTES, masks, 2 * (HORST_LOGT - 2) * HASH_BYTES);
            }
            // Hash from level 15 to 16

            hs.hash_2n_n_mask(pk, 0, buffer, 0, masks, 2 * (HORST_LOGT - 1) * HASH_BYTES);

            return(0);
        }
Beispiel #2
0
        internal static int horst_sign(HashFunctions hs,
                                       byte[] sig, int sigOff, byte[] pk,
                                       byte[] seed,
                                       byte[] masks,
                                       byte[] m_hash)
        {
            byte[] sk = new byte[HORST_T * HORST_SKBYTES];
            uint   idx;
            int    i, j, k;
            int    sigpos = sigOff;

            byte[] tree = new byte[(2 * HORST_T - 1) * HASH_BYTES]; /* replace by something more memory-efficient? */

            expand_seed(sk, seed);

            // Build the whole tree and save it

            // Generate pk leaves
            for (i = 0; i < HORST_T; i++)
            {
                hs.hash_n_n(tree, (HORST_T - 1 + i) * HASH_BYTES, sk, i * HORST_SKBYTES);
            }

            long offset_in, offset_out;

            for (i = 0; i < HORST_LOGT; i++)
            {
                offset_in  = (1 << (HORST_LOGT - i)) - 1;
                offset_out = (1 << (HORST_LOGT - i - 1)) - 1;
                for (j = 0; j < (1 << (HORST_LOGT - i - 1)); j++)
                {
                    hs.hash_2n_n_mask(tree, (int)((offset_out + j) * HASH_BYTES), tree, (int)((offset_in + 2 * j) * HASH_BYTES), masks, 2 * i * HASH_BYTES);
                }
            }

            // First write 64 hashes from level 10 to the signature
            for (j = 63 * HASH_BYTES; j < 127 * HASH_BYTES; j++)
            {
                sig[sigpos++] = tree[j];
            }

            // Signature consists of HORST_K parts; each part of secret key and HORST_LOGT-4 auth-path hashes
            for (i = 0; i < HORST_K; i++)
            {
                idx = (uint)((m_hash[2 * i] & 0xff) + ((m_hash[2 * i + 1] & 0xff) << 8));

                for (k = 0; k < HORST_SKBYTES; k++)
                {
                    sig[sigpos++] = sk[idx * HORST_SKBYTES + k];
                }

                idx += (uint)(HORST_T - 1);
                for (j = 0; j < HORST_LOGT - 6; j++)
                {
                    idx = ((idx & 1) != 0) ? idx + 1 : idx - 1; // neighbor node
                    for (k = 0; k < HASH_BYTES; k++)
                    {
                        sig[sigpos++] = tree[idx * HASH_BYTES + k];
                    }
                    idx = (idx - 1) / 2; // parent node
                }
            }

            for (i = 0; i < HASH_BYTES; i++)
            {
                pk[i] = tree[i];
            }

            return(HORST_SIGBYTES);
        }