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); }
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;}
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; }
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; }
// 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; }
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); }
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; }
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)); }
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"); }
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); } } }
int main(int argc, char *argv[]) { int res = crypto_sign_open(argv[1], argv[2], argv[3], argv[4], argv[5]); return res; }
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; }