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_sign_ed25519_pk_to_curve25519(unsigned char *curve25519_pk, const unsigned char *ed25519_pk) { ge25519_p3 A; fe25519 x; fe25519 one_minus_y; if (ge25519_has_small_order(ed25519_pk) != 0 || ge25519_frombytes_negate_vartime(&A, ed25519_pk) != 0 || ge25519_is_on_main_subgroup(&A) == 0) { return -1; } fe25519_1(one_minus_y); fe25519_sub(one_minus_y, one_minus_y, A.Y); fe25519_1(x); fe25519_add(x, x, A.Y); fe25519_invert(one_minus_y, one_minus_y); fe25519_mul(x, x, one_minus_y); fe25519_tobytes(curve25519_pk, x); return 0; }