nist_keyunwrap16(const void *ctx, nettle_cipher_func *decrypt,
                 const uint8_t *iv, size_t cleartext_length,
                 uint8_t *cleartext, const uint8_t *ciphertext) {
  uint8_t * R = NULL, A[8] = {0}, I[16] = {0}, B[16] = {0};
  uint64_t A64;
  int i, j, ret;
  size_t n;

  if ((R = o_malloc(cleartext_length)) == NULL)
    return 0;

  n = (cleartext_length/8);
  memcpy(A, ciphertext, 8);
  memcpy(R, ciphertext+8, cleartext_length);

  for (j=5; j>=0; j--) {
    for (i=n-1; i>=0; i--) {

      // B = AES-1(K, (A ^ t) | R[i]) where t = n*j+i
      A64 = ((uint64_t)A[0] << 56) | ((uint64_t)A[1] << 48) | ((uint64_t)A[2] << 40) | ((uint64_t)A[3] << 32) | ((uint64_t)A[4] << 24) | ((uint64_t)A[5] << 16) | ((uint64_t)A[6] << 8) | (uint64_t)A[7];
      A64 ^= (n*j)+(i+1);
      I[7] = (uint8_t)A64;
      I[6] = (uint8_t)(A64 >> 8);
      I[5] = (uint8_t)(A64 >> 16);
      I[4] = (uint8_t)(A64 >> 24);
      I[3] = (uint8_t)(A64 >> 32);
      I[2] = (uint8_t)(A64 >> 40);
      I[1] = (uint8_t)(A64 >> 48);
      I[0] = (uint8_t)(A64 >> 56);
      memcpy(I+8, R+(i*8), 8);
      decrypt(ctx, 16, B, I);

      // A = MSB(64, B)
      memcpy(A, B, 8);

      // R[i] = LSB(64, B)
      memcpy(R+(i*8), B+8, 8);
    }
  }

  if (memeql_sec(A, iv, 8)) {
    memcpy(cleartext, R, cleartext_length);
    ret = 1;
  } else {
    ret = 0;
  }
  o_free(R);
  return ret;
}
nist_keyunwrap16(const void *ctx, nettle_cipher_func *decrypt,
                 const uint8_t *iv, size_t cleartext_length,
                 uint8_t *cleartext, const uint8_t *ciphertext) {
  uint8_t * R = NULL, A[8] = {0}, I[16] = {0}, B[16] = {0};
  uint64_t A64;
  int i, j, ret;
  size_t n;

  if ((R = o_malloc(cleartext_length)) == NULL)
    return 0;

  n = (cleartext_length/8);
  memcpy(A, ciphertext, 8);
  memcpy(R, ciphertext+8, cleartext_length);

  for (j=5; j>=0; j--) {
    for (i=n-1; i>=0; i--) {

       
      A64 = ((uint64_t)A[0] << 56) | ((uint64_t)A[1] << 48) | ((uint64_t)A[2] << 40) | ((uint64_t)A[3] << 32) | ((uint64_t)A[4] << 24) | ((uint64_t)A[5] << 16) | ((uint64_t)A[6] << 8) | (uint64_t)A[7];
      A64 ^= (n*j)+(i+1);
      I[7] = (uint8_t)A64;
      I[6] = (uint8_t)(A64 >> 8);
      I[5] = (uint8_t)(A64 >> 16);
      I[4] = (uint8_t)(A64 >> 24);
      I[3] = (uint8_t)(A64 >> 32);
      I[2] = (uint8_t)(A64 >> 40);
      I[1] = (uint8_t)(A64 >> 48);
      I[0] = (uint8_t)(A64 >> 56);
      memcpy(I+8, R+(i*8), 8);
      decrypt(ctx, 16, B, I);

       
      memcpy(A, B, 8);

       
      memcpy(R+(i*8), B+8, 8);
    }
  }

  if (memeql_sec(A, iv, 8)) {
    memcpy(cleartext, R, cleartext_length);
    ret = 1;
  } else {
    ret = 0;
  }
  o_free(R);
  return ret;
}