Exemple #1
0
void crypto_sha512hmac(uint8_t* hash, uint8_t* salt, uint8_t salt_length, uint8_t* data, uint8_t data_length)
{
  uint8_t message1[128 + data_length];
  uint8_t message2[128 + 64];

  memset(message1, 0x36, 128);
  memset(message2, 0x5C, 128);
  for (unsigned i = salt_length; i--; )
  {
    message1[i] = 0x36 ^ salt[i];
    message2[i] = 0x5C ^ salt[i];
  }
  memcpy(message1 + 128, data, data_length);
  crypto_hash_sha512(message2 + 128, message1, sizeof(message1));
  crypto_hash_sha512(hash, message2, sizeof(message2));
}
Exemple #2
0
static char * createGUID()
{
  sodium_init();

  unsigned char out[crypto_hash_sha512_BYTES];
  unsigned char sk[crypto_sign_SECRETKEYBYTES];
  int valid_pow = 0;
  while (valid_pow == 0){

    //Generate a key pair
    unsigned char pk[crypto_sign_PUBLICKEYBYTES];
    unsigned char sk[crypto_sign_SECRETKEYBYTES];
    crypto_sign_keypair(pk, sk);

    //Sign the public key
    const unsigned char * message = pk;
    int message_len = crypto_sign_PUBLICKEYBYTES;

    unsigned char signed_message[crypto_sign_BYTES + message_len];
    unsigned long long signed_message_len;

    crypto_sign(signed_message, &signed_message_len,
            message, message_len, sk);

    //Hash the signed key with sha512
    crypto_hash_sha512(out, signed_message, signed_message_len);
    char proof_of_work[32];
    memcpy(proof_of_work, &out[32], 32);
    char * pow = to_hex(proof_of_work, 3);
    valid_pow = test_pow(pow);
  }
  to_hex(sk, 32);
  return to_hex(sk, 32);
}
Exemple #3
0
int main(void)
{
  size_t i;
  crypto_hash_sha512(h,x,sizeof x - 1U);
  for (i = 0;i < crypto_hash_sha512_BYTES;++i) printf("%02x",(unsigned int) h[i]);
  printf("\n");
  return 0;
}
int crypto_sign_seckey_expand(unsigned char *sk, const unsigned char *skseed)
{
  crypto_hash_sha512(sk,skseed,32);
  sk[0] &= 248;
  sk[31] &= 63;
  sk[31] |= 64;

  return 0;
}
Exemple #5
0
static void get_hram(unsigned char *hram, const unsigned char *sm, const unsigned char *pk, unsigned char *playground, unsigned long long smlen)
{
  unsigned long long i;

  for (i =  0;i < 32;++i)    playground[i] = sm[i];
  for (i = 32;i < 64;++i)    playground[i] = pk[i-32];
  for (i = 64;i < smlen;++i) playground[i] = sm[i];

  crypto_hash_sha512(hram,playground,smlen);
}
Exemple #6
0
/* NEW: Compare to pristine crypto_sign() 
   Uses explicit private key for nonce derivation and as scalar,
   instead of deriving both from a master key.
*/
int crypto_sign_modified(
  unsigned char *sm,
  const unsigned char *m,unsigned long long mlen,
  const unsigned char *sk, const unsigned char* pk,
  const unsigned char* random
)
{
  unsigned char nonce[64];
  unsigned char hram[64];
  ge_p3 R;
  int count=0;

  memmove(sm + 64,m,mlen);
  memmove(sm + 32,sk,32); /* NEW: Use privkey directly for nonce derivation */

  /* NEW : add prefix to separate hash uses - see .h */
  sm[0] = 0xFE;
  for (count = 1; count < 32; count++)
    sm[count] = 0xFF;

  /* NEW: add suffix of random data */
  memmove(sm + mlen + 64, random, 64);

  crypto_hash_sha512(nonce,sm,mlen + 128);
  memmove(sm + 32,pk,32);

  sc_reduce(nonce);
  ge_scalarmult_base(&R,nonce);
  ge_p3_tobytes(sm,&R);

  crypto_hash_sha512(hram,sm,mlen + 64);
  sc_reduce(hram);
  sc_muladd(sm + 32,hram,sk,nonce); /* NEW: Use privkey directly */

  /* NEW: Try to erase any traces of privkey or 
     nonce left in the stack from sc_muladd. */
  zeroize_stack();

  zeroize(nonce, 64);
  return 0;
}
Exemple #7
0
PyObject *pycrypto_hash_sha512(PyObject *self, PyObject *args, PyObject *kw){
  char *m;
  Py_ssize_t msize=0;
  unsigned char h[crypto_hash_sha512_BYTES];
  static const char *kwlist[] = {"m",0};

  if (!PyArg_ParseTupleAndKeywords(args, kw, "|s#:crypto_hash_sha512", (char **)kwlist, &m, &msize)){
    return (PyObject *)0;}

  crypto_hash_sha512(h, (const unsigned char *)m, msize);

  return PyBytes_FromStringAndSize((char *)h, crypto_hash_sha512_BYTES);}
Exemple #8
0
int crypto_sign_ed25519_tinynacl(unsigned char *sm, unsigned long long *smlen, const unsigned char *m, unsigned long long n, const unsigned char *skorig) {

    long long i;
    unsigned char nonce[64], hram[64], sk[64], pk[32];
    ge25519 R;

    /* compute secret key from seed sk = H(skorig), H = sha512 */
    crypto_hash_sha512(sk, skorig, 32);
    sk[0] &= 248;
    sk[31] &= 63;
    sk[31] |= 64;

    /* copy m to sm, copy secret key and public key */
    *smlen = n + 64;
    for (i = 31; i >= 0; --i) pk[i     ] = skorig[i + 32];
    for (i = n - 1; i >= 0; --i) sm[i + 64] = m[i];
    for (i = 31; i >= 0; --i) sm[i + 32] = sk[i + 32];

    /* get pseudorandom nonce = H(sk2, m) */
    crypto_hash_sha512(nonce, sm + 32, n + 32);
    sc25519_reduce(nonce);

    /* copy pk to sm */
    for (i = 31; i >= 0; --i) sm[i + 32] = pk[i];

    /* compute R */
    ge25519_scalarmult_base(R, nonce);
    ge25519_tobytes(sm, R);

    /* calculate hram = H(r, a, m) */
    crypto_hash_sha512(hram, sm, n + 64);
    sc25519_reduce(hram);

    /* compute S */
    sc25519_muladd(sm + 32, hram, sk, nonce);

    /* cleanup */
    cleanup(nonce); cleanup(hram); cleanup(sk); cleanup(pk); cleanup(R);
    return 0;
}
Exemple #9
0
int crypto_sign_ed25519_tinynacl_open(unsigned char *m, unsigned long long *mlen, const unsigned char *sm, unsigned long long n, const unsigned char *pk) {

    long long i;
    unsigned char pkcopy[32], rcopy[32], scopy[32], hram[64], rcheck[32];
    ge25519 R, S, A;
    int ret = -1;

    /* check input */
    if (n < 64) goto fail;
    if (sm[63] & 224) goto fail;

    /* unpack pk */
    if (ge25519_frombytes_negate_vartime(A, pk) != 0) goto fail;

    /* copy pk, r, s */
    for (i = 0; i < 32; ++i) pkcopy[i] = pk[i];
    for (i = 0; i < 32; ++i) rcopy[i]  = sm[i];
    for (i = 0; i < 32; ++i) scopy[i]  = sm[i + 32];

    /* copy sm to m and copy pk to m */
    for (i = n - 1; i >= 0; --i) m[i] = sm[i];
    for (i = 0; i < 32; ++i) m[i + 32] = pkcopy[i];

    /* calculate hram = H(r, a, m) */
    crypto_hash_sha512(hram, m, n);
    sc25519_reduce(hram);

    /* compute R */
    ge25519_scalarmult(A, A, hram);
    ge25519_scalarmult_base(S, scopy);
    ge25519_add(R, S, A);

    /* check R */
    ge25519_tobytes(rcheck, R);
    if (crypto_verify_32(rcheck, rcopy) != 0) goto fail;

    /* copy message */
    n -= 64; *mlen = n;
    for (i = 0; i <  n; ++i) m[i] = m[i + 64];
    for (i = 0; i < 64; ++i) m[i + n] = 0;
    ret = 0;
    goto cleanup;

fail:
    for (i = 0; i < n; ++i) m[i] = 0;

cleanup:
    cleanup(pkcopy); cleanup(rcopy); cleanup(scopy);
    cleanup(hram); cleanup(rcheck);
    cleanup(R); cleanup(S); cleanup(A);
    return ret;
}
int
crypto_box_curve25519xsalsa20poly1305_seed_keypair(unsigned char *pk,
                                                   unsigned char *sk,
                                                   const unsigned char *seed)
{
    unsigned char hash[64];

    crypto_hash_sha512(hash, seed, 32);
    memcpy(sk, hash, 32);
    sodium_memzero(hash, sizeof hash);

    return crypto_scalarmult_curve25519_base(pk, sk);
}
Exemple #11
0
int crypto_sign_edwards25519sha512batch_keypair(unsigned char *pk,
                                                unsigned char *sk)
{
    ge_p3 A;

    randombytes_buf(sk, 32);
    crypto_hash_sha512(sk, sk, 32);
    sk[0] &= 248;
    sk[31] &= 63;
    sk[31] |= 64;
    ge_scalarmult_base(&A, sk);
    ge_p3_tobytes(pk, &A);

    return 0;
}
Exemple #12
0
int main()
{
  struct stat st;
  int ch;

  if (fstat(0,&st) == 0) {
    input = mmap(0,st.st_size,PROT_READ,MAP_SHARED,0,0);
    if (input != MAP_FAILED) {
      crypto_hash_sha512(h,input,st.st_size);
      h_print();
      return 0;
    }
  }

  input = 0;
  inputalloc = 0;
  inputlen = 0;

  while ((ch = getchar()) != EOF) {
    if (inputlen >= inputalloc) {
      void *newinput;
      while (inputlen >= inputalloc)
        inputalloc = inputalloc * 2 + 1;
      if (posix_memalign(&newinput,16,inputalloc) != 0) return 111;
      memcpy(newinput,input,inputlen);
      free(input);
      input = newinput;
    }
    input[inputlen++] = ch;
  }

  crypto_hash_sha512(h,input,inputlen);
  h_print();

  return 0;
}
Exemple #13
0
int keyring_identity_mac(keyring_context *c,keyring_identity *id,
			 unsigned char *pkrsalt,unsigned char *mac)
{
  int ofs;
  unsigned char work[65536];
#define APPEND(b,l) if (ofs+(l)>=65536) { bzero(work,ofs); return WHY("Input too long"); } bcopy((b),&work[ofs],(l)); ofs+=(l)

  ofs=0;
  APPEND(&pkrsalt[0],32);
  APPEND(id->keypairs[0]->private_key,id->keypairs[0]->private_key_len);
  APPEND(id->keypairs[0]->public_key,id->keypairs[0]->public_key_len);
  APPEND(id->PKRPin,strlen(id->PKRPin));
  crypto_hash_sha512(mac,work,ofs);
  return 0;
}
Exemple #14
0
int crypto_sign_ed25519_sk_to_curve25519(unsigned char *curve25519_sk,
                                         const unsigned char *ed25519_sk)
{
    unsigned char h[crypto_hash_sha512_BYTES];

    crypto_hash_sha512(h, ed25519_sk,
                       crypto_sign_ed25519_SECRETKEYBYTES -
                       crypto_sign_ed25519_PUBLICKEYBYTES);
    h[0] &= 248;
    h[31] &= 127;
    h[31] |= 64;
    memcpy(curve25519_sk, h, crypto_scalarmult_curve25519_BYTES);
    sodium_memzero(h, sizeof h);

    return 0;
}
Exemple #15
0
int
_crypto_sign_ed25519_detached(unsigned char *sig, unsigned long long *siglen_p,
                              const unsigned char *m, unsigned long long mlen,
                              const unsigned char *sk, int prehashed)
{
    crypto_hash_sha512_state hs;
    unsigned char            az[64];
    unsigned char            nonce[64];
    unsigned char            hram[64];
    ge_p3                    R;

    _crypto_sign_ed25519_ref10_hinit(&hs, prehashed);

#ifdef ED25519_NONDETERMINISTIC
    memcpy(az, sk, 32);
    _crypto_sign_ed25519_synthetic_r_hv(&hs, nonce, az);
#else
    crypto_hash_sha512(az, sk, 32);
    crypto_hash_sha512_update(&hs, az + 32, 32);
#endif

    crypto_hash_sha512_update(&hs, m, mlen);
    crypto_hash_sha512_final(&hs, nonce);

    memmove(sig + 32, sk + 32, 32);

    sc_reduce(nonce);
    ge_scalarmult_base(&R, nonce);
    ge_p3_tobytes(sig, &R);

    _crypto_sign_ed25519_ref10_hinit(&hs, prehashed);
    crypto_hash_sha512_update(&hs, sig, 64);
    crypto_hash_sha512_update(&hs, m, mlen);
    crypto_hash_sha512_final(&hs, hram);

    sc_reduce(hram);
    _crypto_sign_ed25519_clamp(az);
    sc_muladd(sig + 32, hram, az, nonce);

    sodium_memzero(az, sizeof az);
    sodium_memzero(nonce, sizeof nonce);

    if (siglen_p != NULL) {
        *siglen_p = 64U;
    }
    return 0;
}
Exemple #16
0
int crypto_sign_edwards25519sha512batch_open(unsigned char *m,
                                             unsigned long long *mlen_p,
                                             const unsigned char *sm,
                                             unsigned long long smlen,
                                             const unsigned char *pk)
{
    unsigned char h[64];
    unsigned char t1[32], t2[32];
    unsigned long long mlen;
    ge_cached Ai;
    ge_p1p1 csa;
    ge_p2 cs;
    ge_p3 A;
    ge_p3 R;
    ge_p3 cs3;

    *mlen_p = 0;
    if (smlen < 64 || smlen > SIZE_MAX) {
        return -1;
    }
    mlen = smlen - 64;
    if (sm[smlen - 1] & 224) {
        return -1;
    }
    if (ge_frombytes_negate_vartime(&A, pk) != 0 ||
        ge_frombytes_negate_vartime(&R, sm) != 0) {
        return -1;
    }
    ge_p3_to_cached(&Ai, &A);
    crypto_hash_sha512(h, sm, mlen + 32);
    sc_reduce(h);
    ge_scalarmult_vartime(&cs3, h, &R);
    ge_add(&csa, &cs3, &Ai);
    ge_p1p1_to_p2(&cs, &csa);
    ge_tobytes(t1, &cs);
    t1[31] ^= 1 << 7;
    ge_scalarmult_base(&R, sm + 32 + mlen);
    ge_p3_tobytes(t2, &R);
    if (crypto_verify_32(t1, t2) != 0) {
        return -1;
    }
    *mlen_p = mlen;
    memmove(m, sm + 32, mlen);

    return 0;
}
int crypto_sign_compute_public_key(const unsigned char *skin, unsigned char *pk)
{
  IN();
  unsigned char h[64];
  ge_p3 A;

  crypto_hash_sha512(h,skin,32);
  h[0] &= 248;
  h[31] &= 63;
  h[31] |= 64;

  ge_scalarmult_base(&A,h);
  ge_p3_tobytes(pk,&A);

  RETURN(0);
  OUT();
}
Exemple #18
0
int
crypto_sign_detached(unsigned char *sig, unsigned long long *siglen,
                     const unsigned char *m, unsigned long long mlen,
                     const unsigned char *sk)
{
    crypto_hash_sha512_state hs;
    unsigned char pk[32];
    unsigned char az[64];
    unsigned char nonce[64];
    unsigned char hram[64];
    ge_p3 R;

    memmove(pk, sk + 32, 32);

    crypto_hash_sha512(az, sk, 32);
    az[0] &= 248;
    az[31] &= 63;
    az[31] |= 64;

    crypto_hash_sha512_init(&hs);
    crypto_hash_sha512_update(&hs, az + 32, 32);
    crypto_hash_sha512_update(&hs, m, mlen);
    crypto_hash_sha512_final(&hs, nonce);

    memmove(sig + 32, pk, 32);

    sc_reduce(nonce);
    ge_scalarmult_base(&R, nonce);
    ge_p3_tobytes(sig, &R);

    crypto_hash_sha512_init(&hs);
    crypto_hash_sha512_update(&hs, sig, 64);
    crypto_hash_sha512_update(&hs, m, mlen);
    crypto_hash_sha512_final(&hs, hram);

    sc_reduce(hram);
    sc_muladd(sig + 32, hram, az, nonce);

    sodium_memzero(az, sizeof az);
    sodium_memzero(nonce, sizeof nonce);

    if (siglen != NULL) {
        *siglen = 64U;
    }
    return 0;
}
Exemple #19
0
int crypto_sign_seed_keypair(unsigned char *pk, unsigned char *sk,
                             const unsigned char *seed)
{
    ge_p3 A;

    crypto_hash_sha512(sk,seed,32);
    sk[0] &= 248;
    sk[31] &= 63;
    sk[31] |= 64;

    ge_scalarmult_base(&A,sk);
    ge_p3_tobytes(pk,&A);

    memmove(sk, seed, 32);
    memmove(sk + 32, pk, 32);
    return 0;
}
// sign the hash of a message, adding the signature to the end of the message buffer.
int crypto_sign_message(struct keyring_identity *identity, unsigned char *content, size_t buffer_len, size_t *content_len)
{
  if (*content_len + SIGNATURE_BYTES > buffer_len)
    return WHYF("Insufficient space in message buffer to add signature. %zu, need %zu",buffer_len, *content_len + SIGNATURE_BYTES);
  
  struct keypair *key = keyring_find_sas_private(keyring, identity);
  if (!key)
    return WHY("Could not find signing key");
  
  unsigned char hash[crypto_hash_sha512_BYTES];
  crypto_hash_sha512(hash, content, *content_len);
  
  int sig_length = SIGNATURE_BYTES;
  
  int ret=crypto_create_signature(key->private_key, hash, crypto_hash_sha512_BYTES, &content[*content_len], &sig_length);
  *content_len+=sig_length;
  return ret;
}
Exemple #21
0
int crypto_sign_keypair(unsigned char *pk,unsigned char *sk)
{
  unsigned char h[64];
  ge_p3 A;
  int i;

  randombytes(sk,32);
  crypto_hash_sha512(h,sk,32);
  h[0] &= 248;
  h[31] &= 63;
  h[31] |= 64;

  ge_scalarmult_base(&A,h);
  ge_p3_tobytes(pk,&A);

  for (i = 0;i < 32;++i) sk[32 + i] = pk[i];
  return 0;
}
// verify the signature at the end of a message, on return message_len will be reduced by the length of the signature.
int crypto_verify_message(struct subscriber *subscriber, unsigned char *message, int *message_len)
{
  if (!subscriber->sas_valid){
    keyring_send_sas_request(subscriber);
    return WHY("SAS key not currently on record, cannot verify");
  }
  
  if (*message_len < SIGNATURE_BYTES)
    return WHY("Message is too short to include a signature");
  
  *message_len -= SIGNATURE_BYTES;
  
  unsigned char hash[crypto_hash_sha512_BYTES];
  crypto_hash_sha512(hash,message,*message_len);
  
  return crypto_verify_signature(subscriber->sas_public, hash, 
				 crypto_hash_sha512_BYTES, &message[*message_len], SIGNATURE_BYTES);
}
Exemple #23
0
int crypto_sign_open(
    unsigned char *m,unsigned long long *mlen,
    const unsigned char *sm,unsigned long long smlen,
    const unsigned char *pk
    )
{
  unsigned char pkcopy[32];
  unsigned char rcopy[32];
  unsigned char hram[64];
  unsigned char rcheck[32];
  ge25519 get1, get2;
  sc25519 schram, scs;

  if (smlen < 64) goto badsig;
  if (sm[63] & 224) goto badsig;
  if (ge25519_unpackneg_vartime(&get1,pk)) goto badsig;

  memmove(pkcopy,pk,32);
  memmove(rcopy,sm,32);

  sc25519_from32bytes(&scs, sm+32);

  memmove(m,sm,smlen);
  memmove(m + 32,pkcopy,32);
  crypto_hash_sha512(hram,m,smlen);

  sc25519_from64bytes(&schram, hram);

  ge25519_double_scalarmult_vartime(&get2, &get1, &schram, &ge25519_base, &scs);
  ge25519_pack(rcheck, &get2);

  if (crypto_verify_32(rcopy,rcheck) == 0) {
    memmove(m,m + 64,smlen - 64);
    memset(m + smlen - 64,0,64);
    *mlen = smlen - 64;
    return 0;
  }

badsig:
  *mlen = (unsigned long long) -1;
  memset(m,0,smlen);
  return -1;
}
Exemple #24
0
int
crypto_sign_ed25519_sk_to_curve25519(unsigned char *curve25519_sk,
                                     const unsigned char *ed25519_sk)
{
    unsigned char h[crypto_hash_sha512_BYTES];

#ifdef ED25519_NONDETERMINISTIC
    memcpy(h, ed25519_sk, 32);
#else
    crypto_hash_sha512(h, ed25519_sk, 32);
#endif
    h[0] &= 248;
    h[31] &= 127;
    h[31] |= 64;
    memcpy(curve25519_sk, h, crypto_scalarmult_curve25519_BYTES);
    sodium_memzero(h, sizeof h);

    return 0;
}
Exemple #25
0
int crypto_sign_ed25519_tinynacl_keypair(unsigned char *pk, unsigned char *sk) {

    unsigned char h[64];
    ge25519 A;
    long long i;

    randombytes(sk, 32);
    crypto_hash_sha512(h, sk, 32);
    h[0] &= 248;
    h[31] &= 63;
    h[31] |= 64;

    ge25519_scalarmult_base(A, h);
    ge25519_tobytes(pk, A);

    for (i = 31; i >= 0; --i) sk[i + 32] = pk[i];
    cleanup(h); cleanup(A);
    return 0;
}
Exemple #26
0
static int serval_create_signature(unsigned char *key,
			const unsigned char *msg,
			const size_t msg_len,
			unsigned char *sig_buffer,
			const size_t sig_size) {
  
  unsigned long long sig_length = SIGNATURE_BYTES;
  
  CHECK(sig_size >= msg_len + SIGNATURE_BYTES,"Signature buffer too small");
  
  unsigned char hash[crypto_hash_sha512_BYTES]; 
  
  crypto_hash_sha512(hash, msg, msg_len); // create sha512 hash of message, which will then be signed
  memcpy(sig_buffer,msg,msg_len);
  
  if (crypto_create_signature(key, hash, crypto_hash_sha512_BYTES, &sig_buffer[msg_len], &sig_length) != 0) // create signature of message hash, append it to end of message
    return 0;
  return 1;
  
error:  
  return 0;
}
Exemple #27
0
int crypto_sign_publickey(
    unsigned char *pk,  // write 32 bytes into this
    unsigned char *sk,  // write 64 bytes into this (seed+pubkey)
    unsigned char *seed // 32 bytes input
    )
{
  unsigned char h[64];
  ge_p3 A;
  int i;

  crypto_hash_sha512(h,seed,32);
  h[0] &= 248;
  h[31] &= 63;
  h[31] |= 64;

  ge_scalarmult_base(&A,h);
  ge_p3_tobytes(pk,&A);

  for (i = 0;i < 32;++i) sk[i] = seed[i];
  for (i = 0;i < 32;++i) sk[32 + i] = pk[i];
  return 0;
}
Exemple #28
0
int
crypto_sign_ed25519_seed_keypair(unsigned char *pk, unsigned char *sk,
                                 const unsigned char *seed)
{
    ge25519_p3 A;

#ifdef ED25519_NONDETERMINISTIC
    memmove(sk, seed, 32);
#else
    crypto_hash_sha512(sk, seed, 32);
#endif
    sk[0] &= 248;
    sk[31] &= 127;
    sk[31] |= 64;

    ge25519_scalarmult_base(&A, sk);
    ge25519_p3_tobytes(pk, &A);

    memmove(sk, seed, 32);
    memmove(sk + 32, pk, 32);

    return 0;
}
Exemple #29
0
int
cmd_serval_verify(svl_crypto_ctx *ctx)
{
  int verdict = 0;
  
  CHECK_ERR(ctx && ctx->msg && ctx->signature[0] && ctx->sas_public[0],"Invalid ctx");
  
  DEBUG("Message to verify:\n%s", ctx->msg);
  
  unsigned char hash[crypto_hash_sha512_BYTES];
  crypto_hash_sha512(hash, ctx->msg, ctx->msg_len);
  
  int sig_ret = crypto_verify_signature(ctx->sas_public,
					hash,
					crypto_hash_sha512_BYTES,
					ctx->signature,
					SIGNATURE_BYTES);
  if (sig_ret == 0)
    verdict = 1;  // successfully verified
    
error:
  return verdict;
}
Exemple #30
0
static int
serval_create_signature(svl_crypto_ctx *ctx)
{
  CHECK(ctx && ctx->sas_private[0] && ctx->msg && ctx->msg_len,"Invalid ctx");
  unsigned long long sig_length = SIGNATURE_BYTES;
  unsigned char hash[crypto_hash_sha512_BYTES]; 
  
  // create sha512 hash of message, which will then be signed
  crypto_hash_sha512(hash, ctx->msg, ctx->msg_len);
  
  // create signature of message hash, append it to end of message
  int sig_ret = crypto_create_signature(ctx->sas_private,
					hash,
					crypto_hash_sha512_BYTES,
					ctx->signature,
					&sig_length);
  if (sig_ret != 0)
    return 0;
  return 1;
  
error:  
  return 0;
}