Example #1
0
bool unit_test_crypto_sign(){
  uint64_t len = HACL_UNIT_TESTS_SIZE * sizeof(uint8_t);
  uint8_t *plaintext = malloc(HACL_UNIT_TESTS_SIZE * sizeof (uint8_t));
  uint8_t *expected_signed_msg = malloc((HACL_UNIT_TESTS_SIZE+64) * sizeof (uint8_t));
  uint8_t *hacl_signed_msg = malloc((HACL_UNIT_TESTS_SIZE+64) * sizeof (uint8_t));
  uint8_t sk[64], pk[32];
  crypto_sign_keypair(pk, sk);
  READ_RANDOM_BYTES(len, plaintext);
  int a, res;
  bool pass = true;
  long long unsigned int smlen;
  for (int i = 0; i < 256; i++){
    tweet_crypto_sign(expected_signed_msg, &smlen, plaintext, i, sk);
    crypto_sign(hacl_signed_msg, &smlen, plaintext, i, sk);
    a = memcmp(hacl_signed_msg, expected_signed_msg, (i+64) * sizeof(uint8_t));
    if (a != 0){
      pass = false;
      printf("crypto_sign failed on input of size %d\n", i);
      break;
    }
    res = crypto_sign_open(hacl_signed_msg, &smlen, expected_signed_msg, i + 64, pk);
    if (res != 0) {
      pass = false;
      printf("crypto_sign_open returned value failed on input of size %d\n", i);
      break;
    }
    a = memcmp(hacl_signed_msg, plaintext, i * sizeof(uint8_t));
    if (a != 0){
      pass = false;
      printf("crypto_sign_open failed on input of size %d\n", i);
      break;
    }
  }
  if (!pass) return pass;
  tweet_crypto_sign(expected_signed_msg, &smlen, plaintext, HACL_UNIT_TESTS_SIZE, sk);
  crypto_sign(hacl_signed_msg, &smlen, plaintext, HACL_UNIT_TESTS_SIZE, sk);
  a = memcmp(hacl_signed_msg, expected_signed_msg, (HACL_UNIT_TESTS_SIZE+64) * sizeof (uint8_t));
  if (a != 0){
    pass = false;
    printf("crypto_sign failed on input of size %d\n.", HACL_UNIT_TESTS_SIZE);
  }
  res = crypto_sign_open(hacl_signed_msg, &smlen, expected_signed_msg, HACL_UNIT_TESTS_SIZE + 64, pk);
  if (res != 0) {
    pass = false;
    printf("crypto_sign_open returned value failed on input of size %d\n", HACL_UNIT_TESTS_SIZE);
  }
  a = memcmp(hacl_signed_msg, plaintext, HACL_UNIT_TESTS_SIZE * sizeof(uint8_t));
  if (a != 0){
    pass = false;
    printf("crypto_sign_open failed on input of size %d\n", HACL_UNIT_TESTS_SIZE);
  }

  free(plaintext);
  free(hacl_signed_msg);
  free(expected_signed_msg);

  return pass;
}
void speed_ed25519()
{
  unsigned long long t[NTIMINGS];
  int i;
  unsigned char pk[32];
  unsigned char sk[64];
  
  // Benchmarking keypair
  for(i=0;i<NTIMINGS;i++)
  {
    t[i] = cpucycles();
    crypto_sign_keypair(pk, sk);
  }
  print_bench("sign_keypair",t,NTIMINGS);

  // Benchmarking sign
  for(i=0;i<NTIMINGS;i++)
  {
    t[i] = cpucycles();
    crypto_sign(sm, &smlen, msg, MLEN, sk);
  }
  print_bench("sign (59 bytes)",t,NTIMINGS);

  // Benchmarking sign_open
  for(i=0;i<NTIMINGS;i++)
  {
    t[i] = cpucycles();
    crypto_sign_open(mo, &mlen, sm, smlen, pk);
  }
  print_bench("sign_open (59 bytes)",t,NTIMINGS);
}
Example #3
0
PyObject *pycrypto_sign_open(PyObject *self, PyObject *args, PyObject *kw){
  const unsigned char *sm, *pk;
  Py_ssize_t smsize=0, pksize=0;
  static const char *kwlist[] = {"sm", "pk", 0}; 
  PyObject *ret;
  unsigned long long smlen, mlen;
  unsigned char *m;

  if (!PyArg_ParseTupleAndKeywords(args, kw, "|s#s#:crypto_sign_open", (char **)kwlist, (char **)&sm, &smsize, (char **)&pk, &pksize)){
    return (PyObject *)0;}

  if (pksize != crypto_sign_PUBLICKEYBYTES){
    return Py_BuildValue("i", 0);}

  smlen = smsize;
  m = PyMem_Malloc(smlen);

  if (!m)
    return PyErr_NoMemory();

  if (crypto_sign_open(m, &mlen, sm, smlen, pk) != 0){
    PyMem_Free(m);
    return Py_BuildValue("i", 0);}

  ret = PyBytes_FromStringAndSize((char *) m, mlen);
  PyMem_Free(m);
  return ret;}
Example #4
0
int main(int argc, char *argv[]) {
    if (argc != 4) error(2,
        "Usage: tweetnacl-verify sign.pub message.signed message.txt");

    // This will also erroneously fail if the file "-" exists
    if (file_exists(argv[3])) errorf(1, "File <%s> exists", argv[3]);

    unsigned char public_key[crypto_sign_PUBLICKEYBYTES];
    read_key(argv[1], public_key, crypto_sign_PUBLICKEYBYTES);

    Content c = read_file(argv[2]);
    unsigned char *m = malloc(c.size);
    // printf("%zu\n", c.size);
    unsigned long long msize;
    int result = crypto_sign_open(m, &msize, c.bytes, c.size, public_key);
    free(c.bytes);
    // printf("%i\n", result);
    if (result == -1) error(1, "Signature failed verification");

    if (strcmp(argv[3], "-") != 0) {
        FILE *out = create_file(argv[3]);
        fwrite(m, msize, 1, out);
        fclose(out);
    } else {
        fwrite(m, msize, 1, stdout);
    }

    free(m);
    return 0;
}
Example #5
0
static int sign_open(lua_State *L) {
	size_t slen;
	unsigned long long mlen;
	unsigned char *smsg = NULL;

	smsg = (unsigned char *)lua_tolstring(L, 1, &slen);
	unsigned char msg[slen];

	size_t klen;
	unsigned char *key;
	key = (unsigned char *)lua_tolstring(L, 2, &klen);
	if (klen != crypto_sign_PUBLICKEYBYTES) {
		lua_pushnil(L);
		lua_pushstring(L, "Invalid sign key");
		return 2;
	}

	if (crypto_sign_open(msg, &mlen, smsg, slen, key) != 0) {
		lua_pushnil(L);
		lua_pushstring(L, "Verification failed");
		return 2;
	}

	lua_pushlstring(L, (char *)msg, mlen);
	return 1;
}
Example #6
0
// Decrypt with the same key but from the message bytes (from bytes)
Message CryptoEngine::DecryptWithPublicKeyAndVerify(const std::vector<unsigned char> message_bytes, const VerificationEngine &ver_engine) {

    // check the public key
    if (ver_engine.public_key().empty()) {
        std::cout << "The recipient public key is empty. Cannot encrypt here." << std::endl;
        throw g_crypto_engine_encryption_failure;
    }

    if (ver_engine.signing_public_key().empty()) {
        std::cout << "The recipient signing public key is empty. Cannot encrypt here." << std::endl;
        throw g_crypto_engine_encryption_failure;
    }

    if (private_key_.empty()) {
        std::cout << "The secret key is empty. Cannot encrypt here." << std::endl;
        throw g_crypto_engine_encryption_failure;
    }

    if (nonce_master_key_.empty()) {
        std::cout << "The master key for deriving the nonce is not valid" << std::endl;
        throw g_crypto_engine_encryption_failure;
    }

    if (context_.empty()) {
        std::cout << "The context identifier for deriving the nonce is not valid" << std::endl;
        throw g_crypto_engine_encryption_failure;
    }

    if (salt_.empty()) {
        std::cout << "The salt for deriving the nonce is not valid" << std::endl;
        throw g_crypto_engine_encryption_failure;
    }

    // Convert bytes to encrypted message
    EncryptedMessage encrypted_msg = EncryptedMessage::FromBytes(message_bytes);

    // decrypt
    std::string clear_text_signed_message = crypto_box_open(encrypted_msg.message(), encrypted_msg.nonce(),
                                                            ver_engine.public_key(), private_key_);

    // take the signature out
    std::string signature = clear_text_signed_message.substr(0,128);

    // verify the signature - if it fails it throws an exception
    std::string signed_message = crypto_sign_open(signature,ver_engine.signing_public_key());

    // remove the signing part and the hash
    std::string message_with_data = clear_text_signed_message.substr(128,clear_text_signed_message.size());

    // Convert to message
    Message message = Message::FromBytesString(message_with_data);

    return message;

}
Example #7
0
int curve25519_verify(const unsigned char* signature,
                      const unsigned char* curve25519_pubkey,
                      const unsigned char* msg, const unsigned long msg_len)
{
  fe mont_x, mont_x_minus_one, mont_x_plus_one, inv_mont_x_plus_one;
  fe one;
  fe ed_y;
  unsigned char ed_pubkey[32];
  unsigned long long some_retval;
  unsigned char verifybuf[MAX_MSG_LEN + 64]; /* working buffer */
  unsigned char verifybuf2[MAX_MSG_LEN + 64]; /* working buffer #2 */

  if (msg_len > MAX_MSG_LEN) {
    return -1;
  }

  /* Convert the Curve25519 public key into an Ed25519 public key.  In
     particular, convert Curve25519's "montgomery" x-coordinate into an
     Ed25519 "edwards" y-coordinate:

     ed_y = (mont_x - 1) / (mont_x + 1)

     NOTE: mont_x=-1 is converted to ed_y=0 since fe_invert is mod-exp

     Then move the sign bit into the pubkey from the signature.
  */
  fe_frombytes(mont_x, curve25519_pubkey);
  fe_1(one);
  fe_sub(mont_x_minus_one, mont_x, one);
  fe_add(mont_x_plus_one, mont_x, one);
  fe_invert(inv_mont_x_plus_one, mont_x_plus_one);
  fe_mul(ed_y, mont_x_minus_one, inv_mont_x_plus_one);
  fe_tobytes(ed_pubkey, ed_y);

  /* Copy the sign bit, and remove it from signature */
  ed_pubkey[31] &= 0x7F;  /* bit should be zero already, but just in case */
  ed_pubkey[31] |= (signature[63] & 0x80);
  memmove(verifybuf, signature, 64);
  verifybuf[63] &= 0x7F;

  memmove(verifybuf+64, msg, msg_len);

  /* Then perform a normal Ed25519 verification, return 0 on success */
  /* The below call has a strange API: */
  /* verifybuf = R || S || message */
  /* verifybuf2 = internal to next call gets a copy of verifybuf, S gets 
     replaced with pubkey for hashing, then the whole thing gets zeroized
     (if bad sig), or contains a copy of msg (good sig) */
  return crypto_sign_open(verifybuf2, &some_retval, verifybuf, 64 + msg_len, ed_pubkey);
}
Example #8
0
bool crypto_sign_detach_open(const uint8_t *m, llu mlen,const uint8_t* sig,
        const uint8_t* pk) {
    uint8_t* sm = malloc(mlen+crypto_sign_BYTES);
    if (sm == NULL) return -1;
    uint8_t* m_ = malloc(mlen+crypto_sign_BYTES);
    if (m == NULL) {free(sm); return -1;}
    for (llu i=0; i<crypto_sign_BYTES; ++i) sm[i] = sig[i];
    for (llu i=0; i<mlen; ++i) sm[crypto_sign_BYTES+i] = m[i];
    llu _;
    int ret =
        crypto_sign_open(m_,&_,sm,mlen+crypto_sign_BYTES,pk);
    free(sm);
    free(m_);
    return ret;
}
Example #9
0
static nif_term_t
salt_sign_open(nif_heap_t *hp, int argc, const nif_term_t argv[])
{
	/* salt_sign_open(Signed_msg, Public_key) -> {ok, Verified_msg} | forged_or_garbled. */
	unsigned long long 	len;
	nif_bin_t 		sm;
	nif_bin_t 		pk;
	nif_bin_t 		pm;
	nif_term_t 		raw;
	nif_term_t 		sub;
	nif_term_t 		tag;

	if (argc != 2)
		return (BADARG);

	/* Unpack arguments ensuring they're suitably typed. */
	if (! enif_inspect_iolist_as_binary(hp, argv[0], &sm))
		return (BADARG);

	if (! enif_inspect_binary(hp, argv[1], &pk))
		return (BADARG);

	/* Check constraints on size. */
	if (sm.size < 1 || sm.size > SALT_MAX_MESSAGE_SIZE)
		return (BADARG);

	if (pk.size != crypto_sign_PUBLICKEYBYTES)
		return (BADARG);

	/* Perform the crypto, potentially adjust signed message size. */
	if (! enif_alloc_binary(sm.size + crypto_sign_BYTES, &pm))
		return (BADARG);

	if (crypto_sign_open(pm.data, &len, sm.data, sm.size, pk.data) != 0) {
		enif_release_binary(&pm);

		return (enif_make_atom(hp, "forged_or_garbled"));
	}
	raw = enif_make_binary(hp, &pm);
	tag = enif_make_atom(hp, "ok");

	if (len != sm.size)
		sub = enif_make_sub_binary(hp, raw, 0, len);
	else
		sub = raw;
	return (enif_make_tuple2(hp, tag, sub));
}
Example #10
0
void read_file(char* filename)
{
  int r;

  FILE *file;
  file=fopen(filename,"rb");
  if(file == NULL)
	printf("Unable to open file!\n");

  r = fread(pk, 1, CRYPTO_PUBLICKEYBYTES, file);
  r = fread(sm, 1, MLEN+CRYPTO_BYTES, file);
  r = fread(&smlen, sizeof(unsigned long long), 1, file);

  fclose(file);

  r = crypto_sign_open(mo, &mlen, sm, smlen, pk);

  if(r==0)
  	printf("Test passed.\n");
  else
	printf("Test failed!\n");
}
Example #11
0
void measure(void)
{
  int i;
  int loop;

  for (loop = 0;loop < LOOPS;++loop) {
    for (i = 0;i <= TIMINGS;++i) {
      cycles[i] = cpucycles();
      crypto_sign_keypair(pk,sk);
    }
    for (i = 0;i < TIMINGS;++i) cycles[i] = cycles[i + 1] - cycles[i];
    printentry(-1,"keypair_cycles",cycles,TIMINGS);

    for (mlen = 0;mlen <= MAXTEST_BYTES;mlen += 1 + mlen / 4) {
      randombytes(m,mlen);

      for (i = 0;i <= TIMINGS;++i) {
        cycles[i] = cpucycles();
        bytes[i] = crypto_sign(sm,&smlen,m,mlen,sk);
	if (bytes[i] == 0) bytes[i] = smlen;
      }
      for (i = 0;i < TIMINGS;++i) cycles[i] = cycles[i + 1] - cycles[i];
      printentry(mlen,"cycles",cycles,TIMINGS);
      printentry(mlen,"bytes",bytes,TIMINGS);

      for (i = 0;i <= TIMINGS;++i) {
        cycles[i] = cpucycles();
        bytes[i] = crypto_sign_open(t,&tlen,sm,smlen,pk);
	if (bytes[i] == 0) bytes[i] = tlen;
      }
      for (i = 0;i < TIMINGS;++i) cycles[i] = cycles[i + 1] - cycles[i];
      printentry(mlen,"open_cycles",cycles,TIMINGS);
      printentry(mlen,"open_bytes",bytes,TIMINGS);
    }
  }
}
Example #12
0
int main(int argc, char *argv[])
{
	int res = crypto_sign_open(argv[1], argv[2], argv[3], argv[4], argv[5]);
	return res;
}
Example #13
0
int crypto_sign_open_batch(
    unsigned char* const m[],unsigned long long mlen[],
    unsigned char* const sm[],const unsigned long long smlen[],
    unsigned char* const pk[], 
    unsigned long long num
    )
{
  int ret = 0;
  unsigned long long i, j;
  shortsc25519 r[MAXBATCH];
  sc25519 scalars[2*MAXBATCH+1];
  ge25519 points[2*MAXBATCH+1];
  unsigned char hram[crypto_hash_sha512_BYTES];
  unsigned long long batchsize;

  for (i = 0;i < num;++i) mlen[i] = -1;

  while (num >= 3) {
    batchsize = num;
    if (batchsize > MAXBATCH) batchsize = MAXBATCH;

    for (i = 0;i < batchsize;++i)
      if (smlen[i] < 64) goto fallback;

    randombytes((unsigned char*)r,sizeof(shortsc25519) * batchsize);

    /* Computing scalars[0] = ((r1s1 + r2s2 + ...)) */
    for(i=0;i<batchsize;i++)
    {
      sc25519_from32bytes(&scalars[i], sm[i]+32); 
      sc25519_mul_shortsc(&scalars[i], &scalars[i], &r[i]);
    }
    for(i=1;i<batchsize;i++)
      sc25519_add(&scalars[0], &scalars[0], &scalars[i]);
    
    /* Computing scalars[1] ... scalars[batchsize] as r[i]*H(R[i],A[i],m[i]) */
    for(i=0;i<batchsize;i++)
    {
      get_hram(hram, sm[i], pk[i], m[i], smlen[i]);
      sc25519_from64bytes(&scalars[i+1],hram);
      sc25519_mul_shortsc(&scalars[i+1],&scalars[i+1],&r[i]);
    }
    /* Setting scalars[batchsize+1] ... scalars[2*batchsize] to r[i] */
    for(i=0;i<batchsize;i++)
      sc25519_from_shortsc(&scalars[batchsize+i+1],&r[i]);
  
    /* Computing points */
    points[0] = ge25519_base;
  
    for(i=0;i<batchsize;i++)
      if (ge25519_unpackneg_vartime(&points[i+1], pk[i])) goto fallback;
    for(i=0;i<batchsize;i++)
      if (ge25519_unpackneg_vartime(&points[batchsize+i+1], sm[i])) goto fallback;
  
    ge25519_multi_scalarmult_vartime(points, points, scalars, 2*batchsize+1);
  
    if (ge25519_isneutral_vartime(points)) {
      for(i=0;i<batchsize;i++)
      {
        for(j=0;j<smlen[i]-64;j++)
          m[i][j] = sm[i][j + 64];
        mlen[i] = smlen[i]-64;
      }
    } else {
      fallback:

      for (i = 0;i < batchsize;++i)
        ret |= crypto_sign_open(m[i], &mlen[i], sm[i], smlen[i], pk[i]);
    }

    m += batchsize;
    mlen += batchsize;
    sm += batchsize;
    smlen += batchsize;
    pk += batchsize;
    num -= batchsize;
  }

  for (i = 0;i < num;++i)
    ret |= crypto_sign_open(m[i], &mlen[i], sm[i], smlen[i], pk[i]);

  return ret;
}
int main(void)
{
  volatile unsigned char a; /* Mark the beginning of the stack */

  for(i=0;i<5;i++)
  {
    canary = random();
    WRITE_CANARY(&a);
    crypto_sign_keypair(pk,sk);
    newctr =(unsigned int)&a - (unsigned int)&_end - stack_count(canary);
    ctr = (newctr>ctr)?newctr:ctr;
  }
  print_stack(XSTR(crypto_sign_keypair),-1,ctr);

  for(i=0;i<5;i++)
  {
    canary = random();
    WRITE_CANARY(&a);
    crypto_sign(sm,&smlen,sm,0,sk);
    newctr =(unsigned int)&a - (unsigned int)&_end - stack_count(canary);
    ctr = (newctr>ctr)?newctr:ctr;
  }
  print_stack(XSTR(crypto_sign),0,ctr);

  for(i=0;i<5;i++)
  {
    canary = random();
    WRITE_CANARY(&a);
    crypto_sign_open(sm,&mlen,sm,smlen,pk);
    newctr =(unsigned int)&a - (unsigned int)&_end - stack_count(canary);
    ctr = (newctr>ctr)?newctr:ctr;
  }
  print_stack(XSTR(crypto_sign_open),smlen,ctr);

  for(j=1;j<=MAXTEST_BYTES;j<<=1)
  {
    mlen = j;

    for(i=0;i<5;i++)
    {
      canary = random();
      WRITE_CANARY(&a);
      crypto_sign(sm,&smlen,sm,mlen,sk);
      newctr =(unsigned int)&a - (unsigned int)&_end - stack_count(canary);
      ctr = (newctr>ctr)?newctr:ctr;
    }
    print_stack(XSTR(crypto_sign),mlen,ctr);

    for(i=0;i<5;i++)
    {
      canary = random();
      WRITE_CANARY(&a);
      crypto_sign_open(sm,&mlen,sm,smlen,pk);
      newctr =(unsigned int)&a - (unsigned int)&_end - stack_count(canary);
      ctr = (newctr>ctr)?newctr:ctr;
    }
    print_stack(XSTR(crypto_sign_open),smlen,ctr);
  }

  avr_end();
  return 0;
}