Thread overview
cast to void[]
Feb 12, 2007
Alberto
Feb 12, 2007
Deewiant
Feb 12, 2007
Frits van Bommel
February 12, 2007
I have some problem casting a struct to void[]:

const ushort RSA_ENC_LEN =256;

struct RSAEncryptedData {
  ubyte encoding[RSA_ENC_LEN];
}

struct Signature {
  ubyte sig[RSA_ENC_LEN];
}

class RSA {
  ...
  Signature sign(void[] block, int type=Hash.SHA512);
  bool verifySig(void[] block, Signature sig, int type=Hash.SHA512);
  ...
}

int main() {
	ubyte[32] sessionkey;
	int ret;

	aes128 aes = new aes128(Bits256);
	aes.setRandomKey();
	sessionkey[0..$] = aes.getKey();

	RSA  rsatest = new RSA();
	RSAEncryptedData buf = rsatest.encryptWithPublicKey(sessionkey);

	// #1
	Signature sig = rsatest.sign(cast(void[])buf.encoding, Hash.SHA512);
	ret = rsatest.verifySig(cast(void[])buf.encoding, sig, Hash.SHA512);
	assert(ret == true);

	// #2
	void[] a;
	a.length = RSAEncryptedData.sizeof;
	memcpy(cast(void *)a, cast(void *)&buf, a.length);
	Signature sig2 = rsatest.sign(a, Hash.SHA512);
	ret = rsatest.verifySig(a, sig2, Hash.SHA512);
	assert(ret == true);

	// #3
	Signature sig3 =
rsatest.sign(cast(void[])((&buf)[0..RSAEncryptedData.sizeof]), Hash.SHA512);
	ret =
rsatest.verifySig(cast(void[])((&buf)[0..RSAEncryptedData.sizeof]),
sig3, Hash.SHA512);
	assert(ret == true);

	return 0;
}

I got an Assertion failure on the 3° assert, where I have tried to cast
buf directly to void[].
In general, if I have something like this:

struct pippo {
   ushort a;
   ushort b;
   ubyte[170] c;
   uint d;
}

void do_something(void []);

What is the right way to pass pippo to do_something() ? something like #2 ?
February 12, 2007
Alberto wrote:
> In general, if I have something like this:
> 
> struct pippo {
>    ushort a;
>    ushort b;
>    ubyte[170] c;
>    uint d;
> }
> 
> void do_something(void []);
> 
> What is the right way to pass pippo to do_something() ? something like #2 ?

I came up with the following. It seems idiomatic to me, but there might be something smarter:

struct pippo {
   ushort a;
   ushort b;
   ubyte[170] c;
   uint d;
}

void do_something(void[] foo) {
	pippo* p = cast(pippo*)foo.ptr;
	assert (p.d == 2);
}

void main() {
	pippo p;
	p.d = 2;
	do_something((&p)[0..pippo.sizeof]);
}

-- 
Remove ".doesnotlike.spam" from the mail address.
February 12, 2007
Alberto wrote:
> I have some problem casting a struct to void[]:
> 
[snip]
> 	// #3
> 	Signature sig3 =
> rsatest.sign(cast(void[])((&buf)[0..RSAEncryptedData.sizeof]), Hash.SHA512);
> 	ret =
> rsatest.verifySig(cast(void[])((&buf)[0..RSAEncryptedData.sizeof]),
> sig3, Hash.SHA512);
> 	assert(ret == true);

That RSAEncryptedData.sizeof should be 1, since you're slicing a value of type RSAEncryptedData*.

> 
> 	return 0;
> }
> 
> I got an Assertion failure on the 3° assert, where I have tried to cast
> buf directly to void[].
> In general, if I have something like this:
> 
> struct pippo {
>    ushort a;
>    ushort b;
>    ubyte[170] c;
>    uint d;
> }
> 
> void do_something(void []);
> 
> What is the right way to pass pippo to do_something() ? something like #2 ?

My preferred way is something like
---
pippo somevar;
// ... initialize
do_something((&somevar)[0..1]);
---

(The inner brackets may be superfluous, but I'm not sure. My rule of thumb in such cases is to always put them in there, because even if the code does exactly the same they make it more clear what's happening)