No guards, no nothing, that's correct. but you could write a nice little C# wrapper for it.

Just for the fun of it, would you mind running your .dll through reflector to get a peek at the generated code?
Sure, but why me?

Ok, I used ILSpy.
Here's Sign(..)
/// Signs a message and returns the signature. Returns null on failure.
/// The message to sign. This data is not hashed. For use with bitcoins, you probably want to double-SHA256 hash this before calling this method.
/// The private key to use to sign the message.
public unsafe static byte[] Sign(byte[] message, byte[] privateKey)
{
if (message == null || privateKey == null)
{
throw new ArgumentNullException();
}
if (privateKey.Length != 32)
{
throw new ArgumentOutOfRangeException(Signatures.PrivateKeyLengthError);
}
if (message.Length != 32)
{
throw new ArgumentOutOfRangeException(Signatures.MessageLengthError);
}
int messageptr_3D_cp_1 = 0;
int keyptr_46_cp_1 = 0;
byte[] nonce = new byte[32];
byte[] nonceptr_59_cp_0 = nonce;
int nonceptr_59_cp_1 = 0;
byte[] signature = new byte[72];
byte[] signatureptr_6A_cp_0 = signature;
int signatureptr_6A_cp_1 = 0;
int signaturelen = signature.Length;
byte[] privateKey2;
for (int x = 0; x < 1000; x++)
{
Signatures.Randoms.Value.GetBytes(nonce);
int result = .secp256k1_ecdsa_sign((byte*)(&message[messageptr_3D_cp_1]), message.Length, ref signatureptr_6A_cp_0[signatureptr_6A_cp_1], &signaturelen, (byte*)(&privateKey[keyptr_46_cp_1]), ref nonceptr_59_cp_0[nonceptr_59_cp_1]);
if (result == 1)
{
if (signaturelen == signature.Length)
{
privateKey2 = signature;
}
else
{
byte[] smallsignature = new byte[signaturelen];
Array.Copy(signature, 0, smallsignature, 0, signaturelen);
privateKey2 = smallsignature;
}
return privateKey2;
}
}
privateKey2 = null;
return privateKey2;
}
And here's Verify
/// Verifies that a signature is valid.
/// The message to verify. This data is not hashed. For use with bitcoins, you probably want to double-SHA256 hash this before calling this method.
/// The signature to test for validity. This must not be a compact key (Use RecoverKeyFromCompact instead).
/// The public key used to create the signature.
public unsafe static Signatures.VerifyResult Verify(byte[] message, byte[] signature, byte[] publicKey)
{
if (message == null || signature == null || publicKey == null)
{
throw new ArgumentNullException();
}
if (message.Length != 32)
{
throw new ArgumentOutOfRangeException(Signatures.MessageLengthError);
}
int messageptr_27_cp_1 = 0;
int signatureptr_30_cp_1 = 0;
int keyptr_39_cp_1 = 0;
int result = .secp256k1_ecdsa_verify((byte*)(&message[messageptr_27_cp_1]), message.Length, (byte*)(&signature[signatureptr_30_cp_1]), signature.Length, (byte*)(&publicKey[keyptr_39_cp_1]), publicKey.Length);
int signature2 = result;
Signatures.VerifyResult message2;
if (signature2 != -2)
{
if (signature2 != -1)
{
if (signature2 != 0)
{
if (signature2 != 1)
{
message2 = Signatures.VerifyResult.Error;
}
else
{
message2 = Signatures.VerifyResult.Verified;
}
}
else
{
message2 = Signatures.VerifyResult.SignatureFailed;
}
}
else
{
message2 = Signatures.VerifyResult.InvalidPublicKey;
}
}
else
{
message2 = Signatures.VerifyResult.InvalidSignature;
}
return message2;
}