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 h[64]; unsigned char checkr[32]; ge_p3 A; ge_p2 R; unsigned long long i; *mlen = -1; if (smlen < 64) return -1; if (sm[63] & 224) return -2; if (ge_frombytes_negate_vartime(&A,pk) != 0) return -3; for (i = 0;i < smlen;++i) m[i] = sm[i]; for (i = 0;i < 32;++i) m[32 + i] = pk[i]; SHA512(m, smlen, h); sc_reduce(h); ge_double_scalarmult_vartime(&R,h,&A,sm + 32); ge_tobytes(checkr,&R); if (crypto_verify_32(checkr,sm) != 0) { for (i = 0;i < smlen;++i) m[i] = 0; return crypto_verify_32(checkr,sm); } for (i = 0;i < smlen - 64;++i) m[i] = sm[64 + i]; for (i = smlen - 64;i < smlen;++i) m[i] = 0; *mlen = smlen - 64; return 0; }
enum is_user_enum username_msg_is_user(char *src, size_t slen, char *username, size_t len) { char *uname; size_t uname_len; uint32_t salt; struct username_struct *us = (struct username_struct *) src; unsigned char h[crypto_hash_sha512_BYTES]; if (slen < sizeof(struct username_struct)) { errno = ENOMEM; return USERNAMES_ERR; } uname_len = 512; uname = xzmalloc(uname_len); salt = ntohl(us->salt); slprintf(uname, uname_len, "%s%u", username, salt); crypto_hash_sha512(h, (unsigned char *) uname, strlen(uname)); xfree(uname); if (!crypto_verify_32(&h[0], &us->hash[0]) && !crypto_verify_32(&h[32], &us->hash[32])) return USERNAMES_OK; else return USERNAMES_NE; }
int main(void) { randombytes_buf(v16, sizeof v16); randombytes_buf(v32, sizeof v32); randombytes_buf(v64, sizeof v64); memcpy(v16x, v16, sizeof v16); memcpy(v32x, v32, sizeof v32); memcpy(v64x, v64, sizeof v64); printf("%d\n", crypto_verify_16(v16, v16x)); printf("%d\n", crypto_verify_32(v32, v32x)); printf("%d\n", crypto_verify_64(v64, v64x)); v16x[randombytes_random() & 15U]++; v32x[randombytes_random() & 31U]++; v64x[randombytes_random() & 63U]++; printf("%d\n", crypto_verify_16(v16, v16x)); printf("%d\n", crypto_verify_32(v32, v32x)); printf("%d\n", crypto_verify_64(v64, v64x)); assert(crypto_verify_16_bytes() == 16U); assert(crypto_verify_32_bytes() == 32U); assert(crypto_verify_64_bytes() == 64U); return 0; }
int crypto_auth_hmacsha256_verify(const unsigned char *h,const unsigned char *in,unsigned long long inlen,const unsigned char *k) { unsigned char correct[32]; crypto_auth_hmacsha256(correct,in,inlen,k); return crypto_verify_32(h,correct) | (-(h == correct)) | sodium_memcmp(correct,h,32); }
int cced25519_verify(const struct ccdigest_info *di, size_t mlen, const void *inMsg, const ccec25519signature sig, const ccec25519pubkey pk) { const uint8_t * const m = (const uint8_t *) inMsg; ccdigest_di_decl(di, dc); uint8_t h[64]; uint8_t checkr[32]; ge_p3 A; ge_p2 R; ASSERT_DIGEST_SIZE(di); if (ge_frombytes_negate_vartime(&A,pk) != 0) return -1; ccdigest_init(di,dc); ccdigest_update(di,dc,32,sig); ccdigest_update(di,dc,32,pk); ccdigest_update(di,dc,mlen,m); ccdigest_final(di,dc,h); ccdigest_di_clear(di,dc); sc_reduce(h); ge_double_scalarmult_vartime(&R,h,&A,sig + 32); ge_tobytes(checkr,&R); return crypto_verify_32(checkr,sig); }
int aesctr_packet_get(struct buf *b) { long long len; struct buf *recvbuf = &packet.recvbuf; unsigned char *pp; long long l; /* we need at least one block */ if (recvbuf->len - ZB < BB) { packet.packet_length = 0; return 1; } /* decrypt first block */ if (packet.packet_length == 0) { if (sshcrypto_stream_xor( recvbuf->buf + ZB, /* c */ recvbuf->buf + ZB, /* m */ BB, /* mlen */ packet.clientnonce, /* n */ packet.clientkey /* k */ ) != 0) bug_proto(); packet.packet_length = uint32_unpack_big(recvbuf->buf + ZB); } if (packet.packet_length > PACKET_LIMIT) bug_proto(); if (packet.packet_length + 4 + AB > recvbuf->len - ZB) return 1; /* decrypt and check MAC */ uint32_pack_big(recvbuf->buf + ZB - 4, packet.receivepacketid++); if (sshcrypto_stream_xor( recvbuf->buf + ZB + BB, /* c */ recvbuf->buf + ZB + BB, /* m */ packet.packet_length + 4 - BB, /* mlen */ packet.clientnonce, /* n */ packet.clientkey /* k */ ) != 0) bug_proto(); if (sshcrypto_auth( recvbuf->buf, /* a */ recvbuf->buf + ZB - 4, /* m */ packet.packet_length + 8, /* mlen */ packet.clientmackey /* k */ ) != 0) bug_proto(); if (crypto_verify_32(recvbuf->buf, recvbuf->buf + ZB + packet.packet_length + 4) != 0) bug_proto(); len = packet.packet_length; len -= recvbuf->buf[ZB + 4] + 1; if (len <= 0) bug_proto(); buf_put(b, recvbuf->buf + ZB + 5, len); pp = recvbuf->buf + ZB; l = recvbuf->len - ZB; byte_copy(pp, l - packet.packet_length + AB + 4, pp + packet.packet_length + AB + 4); purge(pp + l - packet.packet_length + AB + 4, packet.packet_length + AB + 4); recvbuf->len -= packet.packet_length + AB + 4; packet.packet_length = 0; purge(recvbuf->buf, ZB); return 1; }
int crypto_sign_open( unsigned char *sm, unsigned long long smlen, const unsigned char *pk ) { unsigned char scopy[32]; unsigned char h[64]; unsigned char rcheck[32]; ge_p3 A; ge_p2 R; if (smlen < 64) goto badsig; if (sm[63] & 224) goto badsig; if (ge_frombytes_negate_vartime(&A,pk) != 0) goto badsig; memmove(scopy,sm + 32,32); memmove(sm + 32,pk,32); crypto_hash_sha512(h,sm,smlen); sc_reduce(h); ge_double_scalarmult_vartime(&R,h,&A,scopy); ge_tobytes(rcheck,&R); if (crypto_verify_32(rcheck,sm) == 0) return 0; badsig: return -1; }
int32_t public_key_cmp(const uint8_t *pk1, const uint8_t *pk2) { #if CRYPTO_PUBLIC_KEY_SIZE != 32 #error CRYPTO_PUBLIC_KEY_SIZE is required to be 32 bytes for public_key_cmp to work, #endif return crypto_verify_32(pk1, pk2); }
int crypto_auth_verify(const unsigned char *h, const unsigned char *in, unsigned long long inlen, const unsigned char *k) { unsigned char correct[32]; crypto_auth(correct,in,inlen,k); return crypto_verify_32(h,correct); }
int crypto_sign_verify(const unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key) { unsigned char h[64]; unsigned char checker[32]; SHA512_CTX hash; ge_p3 A; ge_p2 R; if (signature[63] & 224) { return -1; } if (ge_frombytes_negate_vartime(&A, public_key) != 0) { return -2; } SHA512_Init(&hash); SHA512_Update(&hash, signature, 32); SHA512_Update(&hash, public_key, 32); SHA512_Update(&hash, message, message_len); SHA512_Final(h, &hash); sc_reduce(h); ge_double_scalarmult_vartime(&R, h, &A, signature + 32); ge_tobytes(checker, &R); if (!(crypto_verify_32(checker, signature) == 0)) { return -3; } return 0; }
int fe_isnonzero(const fe f) { static const unsigned char zero[32] = {0}; unsigned char s[32]; fe_tobytes(s,f); return crypto_verify_32(s,zero); }
EncryptedMessage CryptoEngine::EncryptWithPublicKeyAndSign(const Message &message, 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; } // means the current crypto engine and the recipient crypto engine have the same public keys ! // This is NOT SAFE - stop immediately if(crypto_verify_32 (reinterpret_cast<const unsigned char *>(public_key_.data()), reinterpret_cast<const unsigned char *>(ver_engine.public_key().data())) == 0) { std::cout << "The engine public key and the recipient public key are the same !!! Did you copy the same files to two different peers ? This is NOT SAFE !! STOPPING !" << std::endl; throw g_crypto_engine_encryption_failure; } // derive the nonce std::string nonce = hkdf_.DeriveNonce(nonce_master_key_, salt_); // calculate the hash of the data std::string hash(crypto_hash(message.ToBytesString())); // calculate the signature on the hash std::string signed_hash = crypto_sign(hash, sign_private_key_); // prepend the signature+hash to the message std::string signed_message_string = signed_hash + message.ToBytesString(); // encrypt with the recipient public key std::string cipher_text = crypto_box(signed_message_string, nonce, ver_engine.public_key(), private_key_); return EncryptedMessage(nonce, cipher_text); }
int ge_cmp(const ge_p3 *a, const ge_p3 *b) { unsigned char a_comp[ED25519_GE_LENGTH]; unsigned char b_comp[ED25519_GE_LENGTH]; ge_p3_tobytes(a_comp, a); ge_p3_tobytes(b_comp, b); return crypto_verify_32(a_comp, b_comp); }
/* Having duplicate code in tests is better than making them public in real code */ static bool ge_is_zero(const ge_p3 *ge) { uint8_t y[ED25519_GE_LENGTH]; uint8_t z[ED25519_GE_LENGTH]; fe_tobytes(y, ge->Y); fe_tobytes(z, ge->Z); return (!fe_isnonzero(ge->X)) && (!crypto_verify_32(y, z)); }
main(int argc, char **argv) { if (argc<2) { write(2,USAGE,strlen(USAGE)); exit(64); } unsigned char cache[131072*32]={0}; struct passwd *urcd = getpwnam("urcd"); if ((!urcd) || (chdir(argv[1])) || (chroot(argv[1])) || (setgroups(0,'\x00')) || (setgid(urcd->pw_gid)) || (setuid(urcd->pw_uid))) exit(64); unsigned char buffer[16+8+65536+32]; unsigned char hash[32]; int i, n, l; while (1) { readbuffer: if (read(0,buffer,2)<2) exit(1); n = 0; l = 16 + 8 + buffer[0] * 256 + buffer[1]; while (n<l) { i = read(0,buffer+n,l-n); if (i<1) exit(2); n += i; } crypto_hash_sha256(hash,buffer,l); for (i=131072*32-32;i>-32;i-=32) if (!crypto_verify_32(hash,cache+i)) { if (write(1,"\1",1)<1) exit(3); goto readbuffer; } memcpy(cache,cache+32,131072*32-32); memcpy(cache+131072*32-32,hash,32); if (write(1,"\0",1)<1) exit(4); } }
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; }
// Decrypt with the same key but from the message bytes EncryptedMessage CryptoEngine::EncryptWithPublicKey(const Message &message, 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 (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; } // means the current crypto engine and the recipient crypto engine have the same public keys ! // This is NOT SAFE - stop immediately if(crypto_verify_32 (reinterpret_cast<const unsigned char *>(public_key_.data()), reinterpret_cast<const unsigned char *>(ver_engine.public_key().data())) == 0) { std::cout << "The engine public key and the recipient public key are the same !!! Did you copy the same files to two different peers ? This is NOT SAFE !! STOPPING !" << std::endl; throw g_crypto_engine_encryption_failure; } try { // derive the nonce std::string nonce = hkdf_.DeriveNonce(nonce_master_key_, salt_); // Add the additional data (tcp_verion, type, message) to the string std::string full_clear_text(message.ToBytesString()); // encrypt with the recipient public key std::string cipher_text = crypto_box(full_clear_text, nonce, ver_engine.public_key(), private_key_); return EncryptedMessage(nonce, cipher_text); } catch (std::exception& e) { std::cout << "CryptoEngine::Encrypt exception: " << e.what() << std::endl; throw g_crypto_engine_encryption_failure; } }
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 curve25519_proto_init(struct curve25519_proto *p, unsigned char *pubkey_remote, size_t len, char *home, int server) { int fd; ssize_t ret; char path[PATH_MAX]; unsigned char secretkey_own[crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES] = { 0 }; unsigned char publickey_own[crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES] = { 0 }; if (!pubkey_remote || len != crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES) return -EINVAL; memset(path, 0, sizeof(path)); slprintf(path, sizeof(path), "%s/%s", home, FILE_PRIVKEY); fd = open_or_die(path, O_RDONLY); ret = read(fd, secretkey_own, sizeof(secretkey_own)); if (ret != sizeof(secretkey_own)) { xmemset(secretkey_own, 0, sizeof(secretkey_own)); panic("Cannot read private key!\n"); } close(fd); crypto_scalarmult_curve25519_base(publickey_own, secretkey_own); if (!crypto_verify_32(publickey_own, pubkey_remote)) { xmemset(secretkey_own, 0, sizeof(secretkey_own)); xmemset(publickey_own, 0, sizeof(publickey_own)); panic("PANIC: remote end has same public key as you have!!!\n"); } crypto_box_beforenm(p->key, pubkey_remote, secretkey_own); xmemset(p->enonce, 0, sizeof(p->enonce)); xmemset(p->dnonce, 0, sizeof(p->dnonce)); xmemset(secretkey_own, 0, sizeof(secretkey_own)); xmemset(publickey_own, 0, sizeof(publickey_own)); return 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; }
int crypto_sign_verify_detached(const unsigned char *sig, const unsigned char *m, unsigned long long mlen, const unsigned char *pk) { crypto_hash_sha512_state hs; unsigned char h[64]; unsigned char rcheck[32]; unsigned int i; unsigned char d = 0; ge_p3 A; ge_p2 R; #ifdef ED25519_PREVENT_MALLEABILITY if (crypto_sign_check_S_lt_l(sig + 32) != 0) { return -1; } #else if (sig[63] & 224) { return -1; } #endif if (ge_frombytes_negate_vartime(&A, pk) != 0) { return -1; } for (i = 0; i < 32; ++i) { d |= pk[i]; } if (d == 0) { return -1; } crypto_hash_sha512_init(&hs); crypto_hash_sha512_update(&hs, sig, 32); crypto_hash_sha512_update(&hs, pk, 32); crypto_hash_sha512_update(&hs, m, mlen); crypto_hash_sha512_final(&hs, h); sc_reduce(h); ge_double_scalarmult_vartime(&R, h, &A, sig + 32); ge_tobytes(rcheck, &R); return crypto_verify_32(rcheck, sig) | (-(rcheck - sig == 0)) | sodium_memcmp(sig, rcheck, 32); }
int crypto_sign_ed25519_open( unsigned char *m,unsigned long long *mlen, const unsigned char *sm,unsigned long long smlen, const unsigned char *pk ) { unsigned int i; int ret; unsigned char t2[32]; ge25519 get1, get2; sc25519 schram, scs; unsigned char hram[crypto_hash_sha512_BYTES]; *mlen = (unsigned long long) -1; if (smlen < 64) return -1; if (ge25519_unpackneg_vartime(&get1, pk)) return -1; get_hram(hram,sm,pk,m,smlen); sc25519_from64bytes(&schram, hram); sc25519_from32bytes(&scs, sm+32); ge25519_double_scalarmult_vartime(&get2, &get1, &schram, &ge25519_base, &scs); ge25519_pack(t2, &get2); ret = crypto_verify_32(sm, t2); if (!ret) { for(i=0;i<smlen-64;i++) m[i] = sm[i + 64]; *mlen = smlen-64; } else { for(i=0;i<smlen-64;i++) m[i] = 0; } return ret; }
int xed25519_verify(const unsigned char* signature, const unsigned char* curve25519_pubkey, const unsigned char* msg, const unsigned long msg_len) { fe u; fe y; unsigned char ed_pubkey[32]; unsigned char strict[32]; 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. y = (u - 1) / (u + 1) NOTE: u=-1 is converted to y=0 since fe_invert is mod-exp */ fe_frombytes(u, curve25519_pubkey); fe_tobytes(strict, u); if (crypto_verify_32(strict, curve25519_pubkey) != 0) return 0; fe_montx_to_edy(y, u); fe_tobytes(ed_pubkey, y); memmove(verifybuf, signature, 64); 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 */ return crypto_sign_open_modified(verifybuf2, verifybuf, 64 + msg_len, ed_pubkey); }
static nif_term_t salt_verify_32(nif_heap_t *hp, int argc, const nif_term_t argv[]) { /* salt_verify_32(Bin_x, Bin_y) -> equal | not_equal. */ nif_bin_t bx; nif_bin_t by; if (argc != 2) return (BADARG); if (! enif_inspect_binary(hp, argv[0], &bx)) return (BADARG); if (! enif_inspect_binary(hp, argv[1], &by)) return (BADARG); if (bx.size != 32 || by.size != 32) return (BADARG); if (crypto_verify_32(bx.data, by.data) != 0) return (enif_make_atom(hp, "not_equal")); return (enif_make_atom(hp, "equal")); }
SODIUM_EXPORT int crypto_verify_32_ref(const unsigned char *x, const unsigned char *y) { return crypto_verify_32(x, y); }
static void check_config_keypair_or_die(char *home) { int fd, err; ssize_t ret; const char * errstr = NULL; unsigned char publickey[crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES]; unsigned char publicres[crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES]; unsigned char secretkey[crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES]; char path[PATH_MAX]; memset(path, 0, sizeof(path)); slprintf(path, sizeof(path), "%s/%s", home, FILE_PRIVKEY); fd = open(path, O_RDONLY); if (fd < 0) { err = EIO; errstr = "Cannot open privkey file!\n"; goto out_noclose; } ret = read(fd, secretkey, sizeof(secretkey)); if (ret != sizeof(secretkey)) { err = EIO; errstr = "Cannot read private key!\n"; goto out; } close(fd); memset(path, 0, sizeof(path)); slprintf(path, sizeof(path), "%s/%s", home, FILE_PUBKEY); fd = open(path, O_RDONLY); if (fd < 0) { err = EIO; errstr = "Cannot open pubkey file!\n"; goto out_noclose; } ret = read(fd, publickey, sizeof(publickey)); if (ret != sizeof(publickey)) { err = EIO; errstr = "Cannot read public key!\n"; goto out; } crypto_scalarmult_curve25519_base(publicres, secretkey); err = crypto_verify_32(publicres, publickey); if (err) { err = EINVAL; errstr = "WARNING: your keypair is corrupted!!! You need to " "generate new keys!!!\n"; goto out; } out: close(fd); out_noclose: xmemset(publickey, 0, sizeof(publickey)); xmemset(publicres, 0, sizeof(publicres)); xmemset(secretkey, 0, sizeof(secretkey)); if (err) panic("%s: %s\n", errstr, strerror(errno)); }
int main(void) { unsigned char *v16, *v16x; unsigned char *v32, *v32x; unsigned char *v64, *v64x; uint32_t r; uint8_t o; int i; v16 = (unsigned char *) sodium_malloc(16); v16x = (unsigned char *) sodium_malloc(16); v32 = (unsigned char *) sodium_malloc(32); v32x = (unsigned char *) sodium_malloc(32); v64 = (unsigned char *) sodium_malloc(64); v64x = (unsigned char *) sodium_malloc(64); for (i = 0; i < 10000; i++) { randombytes_buf(v16, 16); randombytes_buf(v32, 32); randombytes_buf(v64, 64); memcpy(v16x, v16, 16); memcpy(v32x, v32, 32); memcpy(v64x, v64, 64); if (crypto_verify_16(v16, v16x) != 0 || crypto_verify_32(v32, v32x) != 0 || crypto_verify_64(v64, v64x) != 0 || sodium_memcmp(v16, v16x, 16) != 0 || sodium_memcmp(v32, v32x, 32) != 0 || sodium_memcmp(v64, v64x, 64) != 0) { printf("Failed\n"); } } printf("OK\n"); for (i = 0; i < 100000; i++) { r = randombytes_random(); o = (uint8_t) randombytes_random(); if (o == 0) { continue; } v16x[r & 15U] ^= o; v32x[r & 31U] ^= o; v64x[r & 63U] ^= o; if (crypto_verify_16(v16, v16x) != -1 || crypto_verify_32(v32, v32x) != -1 || crypto_verify_64(v64, v64x) != -1 || sodium_memcmp(v16, v16x, 16) != -1 || sodium_memcmp(v32, v32x, 32) != -1 || sodium_memcmp(v64, v64x, 64) != -1) { printf("Failed\n"); } v16x[r & 15U] ^= o; v32x[r & 31U] ^= o; v64x[r & 63U] ^= o; } printf("OK\n"); assert(crypto_verify_16_bytes() == 16U); assert(crypto_verify_32_bytes() == 32U); assert(crypto_verify_64_bytes() == 64U); sodium_free(v16); sodium_free(v16x); sodium_free(v32); sodium_free(v32x); sodium_free(v64); sodium_free(v64x); return 0; }
int fe_isnonzero(const fe f) { unsigned char s[32]; fe_tobytes(s,f); return crypto_verify_32(s,zero); }