static int ssh_curve25519_build_k(ssh_session_t * session) { ssh_curve25519_pubkey k; session->next_crypto->k = bignum_new(); if (session->next_crypto->k == NULL) { return SSH_ERROR; } if (session->server) crypto_scalarmult(k, session->next_crypto->curve25519_privkey, session->next_crypto->curve25519_client_pubkey); else crypto_scalarmult(k, session->next_crypto->curve25519_privkey, session->next_crypto->curve25519_server_pubkey); bignum_bin2bn(k, CURVE25519_PUBKEY_SIZE, session->next_crypto->k); #ifdef DEBUG_CRYPTO ssh_print_hexa("Session server cookie", session->next_crypto->server_kex.cookie, 16); ssh_print_hexa("Session client cookie", session->next_crypto->client_kex.cookie, 16); ssh_print_bignum("Shared secret key", session->next_crypto->k); #endif return 0; }
int main(void) { unsigned char *alicepk = (unsigned char *) sodium_malloc(crypto_scalarmult_BYTES); unsigned char *bobpk = (unsigned char *) sodium_malloc(crypto_scalarmult_BYTES); unsigned char *k = (unsigned char *) sodium_malloc(crypto_scalarmult_BYTES); int ret; assert(alicepk != NULL && bobpk != NULL && k != NULL); crypto_scalarmult_base(alicepk, alicesk); sodium_bin2hex(hex, sizeof hex, alicepk, crypto_scalarmult_BYTES); printf("%s\n", hex); crypto_scalarmult_base(bobpk, bobsk); sodium_bin2hex(hex, sizeof hex, bobpk, crypto_scalarmult_BYTES); printf("%s\n", hex); ret = crypto_scalarmult(k, alicesk, bobpk); assert(ret == 0); sodium_bin2hex(hex, sizeof hex, k, crypto_scalarmult_BYTES); printf("%s\n", hex); ret = crypto_scalarmult(k, bobsk, alicepk); assert(ret == 0); sodium_bin2hex(hex, sizeof hex, k, crypto_scalarmult_BYTES); printf("%s\n", hex); ret = crypto_scalarmult(k, bobsk, small_order_p); assert(ret == -1); sodium_bin2hex(hex, sizeof hex, k, crypto_scalarmult_BYTES); printf("%s\n", hex); sodium_free(bobpk); sodium_free(alicepk); sodium_free(k); assert(crypto_scalarmult_bytes() > 0U); assert(crypto_scalarmult_scalarbytes() > 0U); assert(strcmp(crypto_scalarmult_primitive(), "curve25519") == 0); assert(crypto_scalarmult_bytes() == crypto_scalarmult_curve25519_bytes()); assert(crypto_scalarmult_scalarbytes() == crypto_scalarmult_curve25519_scalarbytes()); assert(crypto_scalarmult_bytes() == crypto_scalarmult_scalarbytes()); return 0; }
static nif_term_t salt_scalarmult(nif_heap_t *hp, int argc, const nif_term_t argv[]) { /* salt_scalarmult(Integer, Group_p) -> Group_q. */ nif_bin_t n; nif_bin_t p; nif_bin_t q; if (argc != 2) return (BADARG); /* Unpack arguments ensuring they're suitably typed. */ if (! enif_inspect_binary(hp, argv[0], &n)) return (BADARG); if (! enif_inspect_binary(hp, argv[1], &p)) return (BADARG); /* Check constraints on size. */ if (n.size != crypto_scalarmult_SCALARBYTES) return (BADARG); if (p.size != crypto_scalarmult_BYTES) return (BADARG); /* Allocate space for plain text. NB: Passing ENOMEM as BADARG. */ if (! enif_alloc_binary(crypto_scalarmult_BYTES, &q)) return (BADARG); crypto_scalarmult(q.data, n.data, p.data); return (enif_make_binary(hp, &q)); }
bool unit_test_scalarmult(){ // Random key values uint8_t *random_bytes = malloc(32 * NUM_SCALARMULT * sizeof(uint8_t)); READ_RANDOM_BYTES(32 * NUM_SCALARMULT, random_bytes); // Storage buffers uint8_t expected_bytes[32], hacl_bytes[32]; int a, b; bool pass = true; for (int i = 0; i < NUM_SCALARMULT; i++){ b = tweet_crypto_scalarmult_base(expected_bytes, random_bytes + 32 * i); b =crypto_scalarmult_base(hacl_bytes, random_bytes + 32 * i); a = memcmp(hacl_bytes, expected_bytes, 16 * sizeof (uint8_t)); if (a != 0){ pass = false; printf("Scalarmult base failed\n"); break; } } for (int i = 0; i < NUM_SCALARMULT / 2; i++){ b = tweet_crypto_scalarmult(expected_bytes, random_bytes + 32 * 2 * i, random_bytes + 32 * (2 * i + 1)); b = crypto_scalarmult(hacl_bytes, random_bytes + 32 * 2 * i, random_bytes + 32 * (2 * i + 1)); a = memcmp(hacl_bytes, expected_bytes, 16 * sizeof (uint8_t)); if (a != 0){ pass = false; printf("crypto_scalarmult failed\n"); break; } } free(random_bytes); return pass; }
int main(void) { unsigned char *k; unsigned char *bobsk; unsigned char *alicepk; int i; k = (unsigned char *) sodium_malloc(crypto_scalarmult_BYTES); bobsk = (unsigned char *) sodium_malloc(crypto_scalarmult_SCALARBYTES); alicepk = (unsigned char *) sodium_malloc(crypto_scalarmult_SCALARBYTES); assert(k != NULL && bobsk != NULL && alicepk != NULL); memcpy(bobsk, bobsk_, crypto_scalarmult_SCALARBYTES); memcpy(alicepk, alicepk_, crypto_scalarmult_SCALARBYTES); crypto_scalarmult(k, bobsk, alicepk); sodium_free(alicepk); sodium_free(bobsk); for (i = 0; i < 32; ++i) { if (i > 0) { printf(","); } else { printf(" "); } printf("0x%02x", (unsigned int)k[i]); if (i % 8 == 7) { printf("\n"); } } sodium_free(k); return 0; }
int crypto_kx_server_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES], unsigned char tx[crypto_kx_SESSIONKEYBYTES], const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES], const unsigned char server_sk[crypto_kx_SECRETKEYBYTES], const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES]) { crypto_generichash_state h; unsigned char q[crypto_scalarmult_BYTES]; unsigned char keys[2 * crypto_kx_SESSIONKEYBYTES]; int i; if (rx == NULL) { rx = tx; } if (tx == NULL) { tx = rx; } if (rx == NULL) { sodium_misuse(); /* LCOV_EXCL_LINE */ } if (crypto_scalarmult(q, server_sk, client_pk) != 0) { return -1; } COMPILER_ASSERT(sizeof keys <= crypto_generichash_BYTES_MAX); crypto_generichash_init(&h, NULL, 0U, sizeof keys); crypto_generichash_update(&h, q, crypto_scalarmult_BYTES); sodium_memzero(q, sizeof q); crypto_generichash_update(&h, client_pk, crypto_kx_PUBLICKEYBYTES); crypto_generichash_update(&h, server_pk, crypto_kx_PUBLICKEYBYTES); crypto_generichash_final(&h, keys, sizeof keys); sodium_memzero(&h, sizeof h); for (i = 0; i < crypto_kx_SESSIONKEYBYTES; i++) { tx[i] = keys[i]; rx[i] = keys[i + crypto_kx_SESSIONKEYBYTES]; } sodium_memzero(keys, sizeof keys); return 0; }
static int generate(void) { unsigned char ge[crypto_scalarmult_BYTES]; unsigned char out[crypto_scalarmult_BYTES]; unsigned char scalar[crypto_scalarmult_SCALARBYTES]; char ge_hex[crypto_scalarmult_BYTES * 2U + 1U]; char out_hex[crypto_scalarmult_BYTES * 2U + 1U]; char scalar_hex[crypto_scalarmult_SCALARBYTES * 2U + 1U]; randombytes(scalar, sizeof scalar); randombytes(ge, sizeof ge); if (crypto_scalarmult(out, scalar, ge) != 0) { return -1; } bin2hex(scalar_hex, sizeof scalar_hex, scalar, sizeof scalar); bin2hex(ge_hex, sizeof ge_hex, ge, sizeof ge); bin2hex(out_hex, sizeof out_hex, out, sizeof out); printf("%s\t%s\t%s\n", scalar_hex, ge_hex, out_hex); return 0; }
int crypto_scalarmult_base(unsigned char *q, const unsigned char *n) { return crypto_scalarmult(q,n,base); }
const char *checksum_compute(void) { long long i; long long j; long long tests; for (i = 0;i < mlen;++i) m[i] = i; for (i = 0;i < nlen;++i) n[i] = i + 1; for (i = 0;i < plen;++i) p[i] = i + 2; for (i = 0;i < qlen;++i) q[i] = i + 3; for (i = 0;i < rlen;++i) r[i] = i + 4; for (i = -16;i < 0;++i) p[i] = rand(); for (i = -16;i < 0;++i) n[i] = rand(); for (i = plen;i < plen + 16;++i) p[i] = rand(); for (i = nlen;i < nlen + 16;++i) n[i] = rand(); for (i = -16;i < plen + 16;++i) p2[i] = p[i]; for (i = -16;i < nlen + 16;++i) n2[i] = n[i]; if (crypto_scalarmult_base(p,n) != 0) return "crypto_scalarmult_base returns nonzero"; for (i = -16;i < nlen + 16;++i) if (n2[i] != n[i]) return "crypto_scalarmult_base overwrites input"; for (i = -16;i < 0;++i) if (p2[i] != p[i]) return "crypto_scalarmult_base writes before output"; for (i = plen;i < plen + 16;++i) if (p2[i] != p[i]) return "crypto_scalarmult_base writes after output"; for (tests = 0;tests < 100;++tests) { for (i = -16;i < 0;++i) q[i] = rand(); for (i = -16;i < 0;++i) p[i] = rand(); for (i = -16;i < 0;++i) m[i] = rand(); for (i = qlen;i < qlen + 16;++i) q[i] = rand(); for (i = plen;i < plen + 16;++i) p[i] = rand(); for (i = mlen;i < mlen + 16;++i) m[i] = rand(); for (i = -16;i < qlen + 16;++i) q2[i] = q[i]; for (i = -16;i < plen + 16;++i) p2[i] = p[i]; for (i = -16;i < mlen + 16;++i) m2[i] = m[i]; if (crypto_scalarmult(q,m,p) != 0) return "crypto_scalarmult returns nonzero"; for (i = -16;i < mlen + 16;++i) if (m2[i] != m[i]) return "crypto_scalarmult overwrites n input"; for (i = -16;i < plen + 16;++i) if (p2[i] != p[i]) return "crypto_scalarmult overwrites p input"; for (i = -16;i < 0;++i) if (q2[i] != q[i]) return "crypto_scalarmult writes before output"; for (i = qlen;i < qlen + 16;++i) if (q2[i] != q[i]) return "crypto_scalarmult writes after output"; if (crypto_scalarmult(m2,m2,p) != 0) return "crypto_scalarmult returns nonzero"; for (i = 0;i < qlen;++i) if (q[i] != m2[i]) return "crypto_scalarmult does not handle n overlap"; for (i = 0;i < qlen;++i) m2[i] = m[i]; if (crypto_scalarmult(p2,m2,p2) != 0) return "crypto_scalarmult returns nonzero"; for (i = 0;i < qlen;++i) if (q[i] != p2[i]) return "crypto_scalarmult does not handle p overlap"; if (crypto_scalarmult(r,n,q) != 0) return "crypto_scalarmult returns nonzero"; if (crypto_scalarmult(q,n,p) != 0) return "crypto_scalarmult returns nonzero"; if (crypto_scalarmult(p,m,q) != 0) return "crypto_scalarmult returns nonzero"; for (j = 0;j < plen;++j) if (p[j] != r[j]) return "crypto_scalarmult not associative"; for (j = 0;j < mlen;++j) m[j] ^= q[j % qlen]; for (j = 0;j < nlen;++j) n[j] ^= p[j % plen]; } sodium_bin2hex(checksum, sizeof checksum, p, crypto_scalarmult_BYTES); return 0; }
void doit(void) { crypto_scalarmult(q,n,p); crypto_scalarmult_base(r,n); }