Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Fast, safe array access - stackalloc equivalent?

Fast, safe array access - stackalloc equivalent?

Scheduled Pinned Locked Moved C#
data-structuresdatabaseperformancehelpquestion
4 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • V Offline
    V Offline
    Vega02
    wrote on last edited by
    #1

    Hey guys. I'm writing a key schedule method for a cryptographic primitive - the signature of this method is void SetKey(byte[] key). The problem I'm encountering is that I don't know the length of the key array before the method is called, but I need to expand it to a fixed length (say, 256 bits) because all manipulation needs to be done on the fixed-length array. I won't need this array any more after the SetKey method has finished, and since the array contains sensitive material I'd like it to be wiped from memory as quickly as possible. I can find four ways to do what I need here: 1. Use something like byte* expanded = stackalloc byte[256 / 8]. The key is declared on the stack, so it will be overwritten on future function calls. Array lookups are also extremely fast, but this code cannot be verified typesafe. The lack of type safety makes it a poor candidate. 2. Create a new array on every execution of the method: byte[] expanded = new byte[256 / 8]. This is typesafe, and I can call Array.Clear before the method returns, but this is dreadfully slow if the SetKey method is called in a loop. 3. Define an array byte[] m_expanded = new byte[256 / 8] in the class containing SetKey. This is typesafe and prevents overworking the garbage collector if SetKey is called in a loop, and I can simply clear the array when the method exits. But putting this temporary array in the class itself seems like bad coding style. 4. For certain primitives, the key needs to be cast to a series of integers, and the key scheduling algorithms operate directly on the integers. I have a structure declared in the class containing SetKey: private struct Block { uint a; uint b; . . . }. Then I can declare Block b; as a local (stack) variable within SetKey and pass ref b as an argument to helper methods (which must operate directly on b). This is typesafe and declared on the stack, so it will be overwritten on future function calls. This only works in cases where the expanded key array is updated in order (index 0, 1, 2, . . ., corresponding to members b.a, b.b, b.c, ...) and where I can unroll the key expanding loop. So this is not a general solution. Currently I'm using (3) for most of my primitives and (4) for a select few. What I'd really

    J L 2 Replies Last reply
    0
    • V Vega02

      Hey guys. I'm writing a key schedule method for a cryptographic primitive - the signature of this method is void SetKey(byte[] key). The problem I'm encountering is that I don't know the length of the key array before the method is called, but I need to expand it to a fixed length (say, 256 bits) because all manipulation needs to be done on the fixed-length array. I won't need this array any more after the SetKey method has finished, and since the array contains sensitive material I'd like it to be wiped from memory as quickly as possible. I can find four ways to do what I need here: 1. Use something like byte* expanded = stackalloc byte[256 / 8]. The key is declared on the stack, so it will be overwritten on future function calls. Array lookups are also extremely fast, but this code cannot be verified typesafe. The lack of type safety makes it a poor candidate. 2. Create a new array on every execution of the method: byte[] expanded = new byte[256 / 8]. This is typesafe, and I can call Array.Clear before the method returns, but this is dreadfully slow if the SetKey method is called in a loop. 3. Define an array byte[] m_expanded = new byte[256 / 8] in the class containing SetKey. This is typesafe and prevents overworking the garbage collector if SetKey is called in a loop, and I can simply clear the array when the method exits. But putting this temporary array in the class itself seems like bad coding style. 4. For certain primitives, the key needs to be cast to a series of integers, and the key scheduling algorithms operate directly on the integers. I have a structure declared in the class containing SetKey: private struct Block { uint a; uint b; . . . }. Then I can declare Block b; as a local (stack) variable within SetKey and pass ref b as an argument to helper methods (which must operate directly on b). This is typesafe and declared on the stack, so it will be overwritten on future function calls. This only works in cases where the expanded key array is updated in order (index 0, 1, 2, . . ., corresponding to members b.a, b.b, b.c, ...) and where I can unroll the key expanding loop. So this is not a general solution. Currently I'm using (3) for most of my primitives and (4) for a select few. What I'd really

      J Offline
      J Offline
      Jared Parsons
      wrote on last edited by
      #2

      Vega02 wrote:

      1. Use something like byte* expanded = stackalloc byte[256 / 8]. The key is declared on the stack, so it will be overwritten on future function calls.

      That statement isn't 100% true. It will only be overwritten when enough nested function calls are made such that the stack height overwrites the array. It's possible that the call to SetKey is the deepest call ever made and thus the data is never overwritten. Jared Parsons jaredp@beanseed.org http://jaredparsons.blogspot.com/[^]

      V 1 Reply Last reply
      0
      • J Jared Parsons

        Vega02 wrote:

        1. Use something like byte* expanded = stackalloc byte[256 / 8]. The key is declared on the stack, so it will be overwritten on future function calls.

        That statement isn't 100% true. It will only be overwritten when enough nested function calls are made such that the stack height overwrites the array. It's possible that the call to SetKey is the deepest call ever made and thus the data is never overwritten. Jared Parsons jaredp@beanseed.org http://jaredparsons.blogspot.com/[^]

        V Offline
        V Offline
        Vega02
        wrote on last edited by
        #3

        This isn't a big deal as far as I'm concerned. If SetKey is the deepest call ever made, then no encryption or decryption routines have been called, hence no data is protected with this key and the key is useless.

        1 Reply Last reply
        0
        • V Vega02

          Hey guys. I'm writing a key schedule method for a cryptographic primitive - the signature of this method is void SetKey(byte[] key). The problem I'm encountering is that I don't know the length of the key array before the method is called, but I need to expand it to a fixed length (say, 256 bits) because all manipulation needs to be done on the fixed-length array. I won't need this array any more after the SetKey method has finished, and since the array contains sensitive material I'd like it to be wiped from memory as quickly as possible. I can find four ways to do what I need here: 1. Use something like byte* expanded = stackalloc byte[256 / 8]. The key is declared on the stack, so it will be overwritten on future function calls. Array lookups are also extremely fast, but this code cannot be verified typesafe. The lack of type safety makes it a poor candidate. 2. Create a new array on every execution of the method: byte[] expanded = new byte[256 / 8]. This is typesafe, and I can call Array.Clear before the method returns, but this is dreadfully slow if the SetKey method is called in a loop. 3. Define an array byte[] m_expanded = new byte[256 / 8] in the class containing SetKey. This is typesafe and prevents overworking the garbage collector if SetKey is called in a loop, and I can simply clear the array when the method exits. But putting this temporary array in the class itself seems like bad coding style. 4. For certain primitives, the key needs to be cast to a series of integers, and the key scheduling algorithms operate directly on the integers. I have a structure declared in the class containing SetKey: private struct Block { uint a; uint b; . . . }. Then I can declare Block b; as a local (stack) variable within SetKey and pass ref b as an argument to helper methods (which must operate directly on b). This is typesafe and declared on the stack, so it will be overwritten on future function calls. This only works in cases where the expanded key array is updated in order (index 0, 1, 2, . . ., corresponding to members b.a, b.b, b.c, ...) and where I can unroll the key expanding loop. So this is not a general solution. Currently I'm using (3) for most of my primitives and (4) for a select few. What I'd really

          L Offline
          L Offline
          leppie
          wrote on last edited by
          #4

          I think using pinned pointers is better in this case. eg

          byte[] buffer = new byte[256];

          fixed (byte* pbuf = buffer)
          {
          // no pbuf will be fixed. You can merribly call subfunctions till the end of the block.
          }

          xacc.ide-0.1.1.4 - now with LSharp integration and scripting :)

          1 Reply Last reply
          0
          Reply
          • Reply as topic
          Log in to reply
          • Oldest to Newest
          • Newest to Oldest
          • Most Votes


          • Login

          • Don't have an account? Register

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • World
          • Users
          • Groups