#include "pgsodium.h" PG_FUNCTION_INFO_V1 (pgsodium_crypto_signcrypt_keypair); Datum pgsodium_crypto_signcrypt_keypair (PG_FUNCTION_ARGS) { TupleDesc tupdesc; Datum values[2]; bool nulls[2] = { false, false }; HeapTuple tuple; Datum result; bytea *publickey; bytea *secretkey; if (get_call_result_type (fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) ereport (ERROR, (errcode (ERRCODE_FEATURE_NOT_SUPPORTED), errmsg ("function returning record called in context " "that cannot accept type record"))); publickey = _pgsodium_zalloc_bytea (crypto_signcrypt_tbsbr_PUBLICKEYBYTES + VARHDRSZ); secretkey = _pgsodium_zalloc_bytea (crypto_signcrypt_tbsbr_SECRETKEYBYTES + VARHDRSZ); crypto_signcrypt_tbsbr_keygen (PGSODIUM_UCHARDATA (publickey), PGSODIUM_UCHARDATA (secretkey)); values[0] = PointerGetDatum (publickey); values[1] = PointerGetDatum (secretkey); tuple = heap_form_tuple (tupdesc, values, nulls); result = HeapTupleGetDatum (tuple); return result; } PG_FUNCTION_INFO_V1 (pgsodium_crypto_signcrypt_sign_before); Datum pgsodium_crypto_signcrypt_sign_before (PG_FUNCTION_ARGS) { bytea *sender = PG_GETARG_BYTEA_P (0); bytea *recipient = PG_GETARG_BYTEA_P (1); bytea *sender_sk = PG_GETARG_BYTEA_P (2); bytea *recipient_pk = PG_GETARG_BYTEA_P (3); bytea *additional = PG_GETARG_BYTEA_P (4); TupleDesc tupdesc; Datum values[2]; bool nulls[2] = { false, false }; HeapTuple tuple; Datum result; bytea *state, *shared_key; int success; if (get_call_result_type (fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) ereport (ERROR, (errcode (ERRCODE_FEATURE_NOT_SUPPORTED), errmsg ("function returning record called in context " "that cannot accept type record"))); state = _pgsodium_zalloc_bytea (crypto_signcrypt_tbsbr_STATEBYTES + VARHDRSZ); shared_key = _pgsodium_zalloc_bytea (crypto_signcrypt_tbsbr_SECRETKEYBYTES + VARHDRSZ); success = crypto_signcrypt_tbsbr_sign_before (PGSODIUM_UCHARDATA (state), PGSODIUM_UCHARDATA (shared_key), PGSODIUM_UCHARDATA (sender), VARSIZE_ANY_EXHDR (sender), PGSODIUM_UCHARDATA (recipient), VARSIZE_ANY_EXHDR (recipient), PGSODIUM_UCHARDATA (additional), VARSIZE_ANY_EXHDR (additional), PGSODIUM_UCHARDATA (sender_sk), PGSODIUM_UCHARDATA (recipient_pk), NULL, 0); ERRORIF (success != 0, "%s: sign_before failed"); values[0] = PointerGetDatum (state); values[1] = PointerGetDatum (shared_key); tuple = heap_form_tuple (tupdesc, values, nulls); result = HeapTupleGetDatum (tuple); return result; } PG_FUNCTION_INFO_V1 (pgsodium_crypto_signcrypt_sign_after); Datum pgsodium_crypto_signcrypt_sign_after (PG_FUNCTION_ARGS) { bytea *state = PG_GETARG_BYTEA_P (0); bytea *sender_sk = PG_GETARG_BYTEA_P (1); bytea *ciphertext = PG_GETARG_BYTEA_P (2); bytea *signature = _pgsodium_zalloc_bytea (crypto_signcrypt_tbsbr_SIGNBYTES + VARHDRSZ); int success; success = crypto_signcrypt_tbsbr_sign_after (PGSODIUM_UCHARDATA (state), PGSODIUM_UCHARDATA (signature), PGSODIUM_UCHARDATA (sender_sk), PGSODIUM_UCHARDATA (ciphertext), VARSIZE_ANY_EXHDR (ciphertext)); ERRORIF (success != 0, "%s: sign_after failed"); PG_RETURN_BYTEA_P (signature); } PG_FUNCTION_INFO_V1 (pgsodium_crypto_signcrypt_verify_before); Datum pgsodium_crypto_signcrypt_verify_before (PG_FUNCTION_ARGS) { bytea *signature = PG_GETARG_BYTEA_P (0); bytea *sender = PG_GETARG_BYTEA_P (1); bytea *recipient = PG_GETARG_BYTEA_P (2); bytea *additional = PG_GETARG_BYTEA_P (3); bytea *sender_pk = PG_GETARG_BYTEA_P (4); bytea *recipient_sk = PG_GETARG_BYTEA_P (5); TupleDesc tupdesc; Datum values[2]; bool nulls[2] = { false, false }; HeapTuple tuple; Datum result; bytea *state, *shared_key; int success; if (get_call_result_type (fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) ereport (ERROR, (errcode (ERRCODE_FEATURE_NOT_SUPPORTED), errmsg ("function returning record called in context " "that cannot accept type record"))); state = _pgsodium_zalloc_bytea (crypto_signcrypt_tbsbr_STATEBYTES + VARHDRSZ); shared_key = _pgsodium_zalloc_bytea (crypto_signcrypt_tbsbr_SECRETKEYBYTES + VARHDRSZ); success = crypto_signcrypt_tbsbr_verify_before (PGSODIUM_UCHARDATA (state), PGSODIUM_UCHARDATA (shared_key), PGSODIUM_UCHARDATA (signature), PGSODIUM_UCHARDATA (sender), VARSIZE_ANY_EXHDR (sender), PGSODIUM_UCHARDATA (recipient), VARSIZE_ANY_EXHDR (recipient), PGSODIUM_UCHARDATA (additional), VARSIZE_ANY_EXHDR (additional), PGSODIUM_UCHARDATA (sender_pk), PGSODIUM_UCHARDATA (recipient_sk)); ERRORIF (success != 0, "%s: verify_before failed"); values[0] = PointerGetDatum (state); values[1] = PointerGetDatum (shared_key); tuple = heap_form_tuple (tupdesc, values, nulls); result = HeapTupleGetDatum (tuple); return result; } PG_FUNCTION_INFO_V1 (pgsodium_crypto_signcrypt_verify_after); Datum pgsodium_crypto_signcrypt_verify_after (PG_FUNCTION_ARGS) { bytea *state = PG_GETARG_BYTEA_P (0); bytea *signature = PG_GETARG_BYTEA_P (1); bytea *sender_pk = PG_GETARG_BYTEA_P (2); bytea *ciphertext = PG_GETARG_BYTEA_P (3); int success; success = crypto_signcrypt_tbsbr_verify_after (PGSODIUM_UCHARDATA (state), PGSODIUM_UCHARDATA (signature), PGSODIUM_UCHARDATA (sender_pk), PGSODIUM_UCHARDATA (ciphertext), VARSIZE_ANY_EXHDR (ciphertext)); ERRORIF (success != 0, "%s: verify_after failed"); PG_RETURN_BOOL (success == 0); } PG_FUNCTION_INFO_V1 (pgsodium_crypto_signcrypt_verify_public); Datum pgsodium_crypto_signcrypt_verify_public (PG_FUNCTION_ARGS) { bytea *signature = PG_GETARG_BYTEA_P (0); bytea *sender = PG_GETARG_BYTEA_P (1); bytea *recipient = PG_GETARG_BYTEA_P (2); bytea *additional = PG_GETARG_BYTEA_P (3); bytea *sender_pk = PG_GETARG_BYTEA_P (4); bytea *ciphertext = PG_GETARG_BYTEA_P (5); int success; success = crypto_signcrypt_tbsr_verify_public (PGSODIUM_UCHARDATA (signature), PGSODIUM_UCHARDATA (sender), VARSIZE_ANY_EXHDR (sender), PGSODIUM_UCHARDATA (recipient), VARSIZE_ANY_EXHDR (recipient), PGSODIUM_UCHARDATA (additional), VARSIZE_ANY_EXHDR (additional), PGSODIUM_UCHARDATA (sender_pk), PGSODIUM_UCHARDATA (ciphertext), VARSIZE_ANY_EXHDR (ciphertext)); ERRORIF (success != 0, "%s: verify_public failed"); PG_RETURN_BOOL (success == 0); }