Click here to Skip to main content
15,895,370 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Good day guys

I'm inserting an array into another array with the Array.copy function. The destination array is fixed. Its a byte[157]. The first 64 elements and the last 77 elements stay the same only the middle 16 elements change. So I say:
<br />
Array.copy(source,0,dest,64,16);<br />

Isn't there a faster way of doing this? I know about memoryStreams but the memoryStream.toArray() eats up performance and it creates a copy of the array which uses memory I don't have. I'm developing on a smart card. Maybe the full code will help. This is a Hmac function used for tls.
C#
private void ComputeMyHMac_hash(ref HashAlgorithm alg, ref byte[] secret, byte[] seed, ref byte[] output,int size)
        {
            #region pads
            #region inpad
            byte[] inpad = { 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
                             0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
                             0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
                             0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
                             0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
                             0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
                             0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
                             0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
                           };
            #endregion
            #region outpad
            byte[] outpad = { 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
                             0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
                             0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
                             0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
                             0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
                             0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
                             0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
                             0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 
                           };
            #endregion
            for (int i = 0; i < secret.Length; i++)
            {
                inpad[i] ^= secret[i];
                outpad[i] ^= secret[i];
            }
            #endregion
            //end init pads
            secret = null;
            byte[] buf = new byte[size];
            byte[] buf2 = new byte[size];
            byte[] worker = new byte[64+size];
            Array.Copy(inpad, worker, inpad.Length);
            byte[] worker2 = new byte[64  + seed.Length];
            Array.Copy(inpad,worker2,inpad.Length);
            Array.Copy(seed, 0, worker2, 64, seed.Length);
            //var for doFinal
            byte[] tmp = new byte[size];
            byte[] worker3 = new byte[64 + size];
            Array.Copy(outpad, worker3, outpad.Length);
            outpad = null;
            
            MemoryStream outStr = new MemoryStream(0);
            int iterations = (output.Length + size - 1) / size;
            for (int i = 0; i < iterations; i++)
            {
                if (i == 0)
                {
                    DoFinal(ref buf, worker2, ref alg, ref tmp, ref worker3);
                    worker2 = new byte[64 + size + seed.Length];
                    Array.Copy(inpad, worker2, inpad.Length);
                    inpad = null;
                    Array.Copy(seed, 0, worker2, 64 +size, seed.Length);
                    ////debug.WriteLine("ComputeMyHMac_hash 1");
                }
                else
                {
                    Array.Copy(seed, 0, worker, 64, seed.Length);
                    DoFinal(ref buf, worker, ref alg, ref tmp, ref worker3);
                }
                seed = buf;
                Array.Copy(seed, 0, worker2, 64, seed.Length);
                DoFinal(ref buf2, worker2, ref alg, ref tmp, ref worker3);
                outStr.Write(buf2, 0, buf2.Length);
            }
            output = outStr.ToArray();
            outStr.Close();
        }
private void DoFinal(ref byte[] buf, byte[] worker, ref HashAlgorithm alg, ref byte[] tmp, ref byte[] worker3)
        {
            tmp = alg.ComputeHash(worker);
            Array.Copy(tmp, 0, worker3, 64, tmp.Length);
            buf = alg.ComputeHash(worker3);
        }


The hash algorithm can be MD5 or Sha1, The size is the size of the hash algorithm either 16 or 20.

Hopefully someone can help. Any advice would be appreciated.
Thanks

Btw: Where can I find the editing tags to make the post look good? To put the code in a nice code block that the indentation is correct?
Posted
Updated 14-Oct-10 21:28pm
v2
Comments
Dalek Dave 15-Oct-10 3:28am    
Edited for Readability
Henry Minute 15-Oct-10 3:46am    
Highlight existing code then click on 'code block' at the top of the editor. If you paste code in it should get blocked automatically, if not check the state of the radio buttons at the bottom.

1 solution

You could make your own copy function that uses a larger data type. If you can be sure that the start and number of items to copy are both always dividable by four, you can use UInt32 for example. If it's always dividable by eight you can use UInt64 (using MMX registers). And if you are actually sure it's always dividable by sixteen you could also use an 128bit data type but you then you would have to write your own assembly code to utilize the XMM registers (and before use, you must make sure they are available.)

There is however a trade of in using the MMX and XMM registers in small operations. You would be forced to use the EMMS instruction and on an earlier pentium 4 this is a very excessive cycle consuming instruction.

In conclusion it would be best to use UInt32 because it doesn't involve any assembly and other trade-offs there might be. As long as the index and the number of bytes to copy are divisible by four there won't be any problem but would speed up copying 4 times because it's moving 4 bytes instead of 1 at a time.

Good luck!
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900