mirror of
https://github.com/open-quantum-safe/liboqs.git
synced 2025-10-06 00:03:35 -04:00
Adding Javad's SIDH IQC implementation
This commit is contained in:
parent
42d38a59f5
commit
6b6afa837f
@ -18,6 +18,10 @@ if [[ ${ENABLE_NTRU} == 1 ]];then
|
||||
enable_disable_str+=" --enable-ntru"
|
||||
fi
|
||||
|
||||
if [[ ${ENABLE_SIDH_IQC_REF} == 1 ]];then
|
||||
enable_disable_str+=" --enable-sidhiqc"
|
||||
fi
|
||||
|
||||
./configure --enable-silent-rules ${enable_disable_str}
|
||||
make clean
|
||||
make
|
||||
|
@ -6,13 +6,14 @@ matrix:
|
||||
include:
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
env: CC_OQS=gcc-4.8
|
||||
env: CC_OQS=gcc-4.8 ENABLE_SIDH_IQC_REF=1
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- gcc-4.8
|
||||
- libgmp-dev
|
||||
before_install:
|
||||
- sh .travis/install-clang-format-linux.sh
|
||||
- os: linux
|
||||
@ -52,9 +53,9 @@ matrix:
|
||||
- bash download-and-build-ntru.sh
|
||||
- os: osx
|
||||
compiler: clang
|
||||
env: CC_OQS=clang AES_NI=0 USE_OPENSSL=1 ENABLE_CODE_MCBITS=1 ENABLE_NTRU=1
|
||||
before_install:
|
||||
- brew install clang-format openssl libsodium
|
||||
env: CC_OQS=clang AES_NI=0 USE_OPENSSL=1 ENABLE_CODE_MCBITS=1 ENABLE_NTRU=1 ENABLE_SIDH_IQC_REF=1
|
||||
before_install:
|
||||
- brew install clang-format openssl libsodium gmp
|
||||
- bash download-and-build-ntru.sh
|
||||
|
||||
script:
|
||||
|
11
Makefile.am
11
Makefile.am
@ -30,6 +30,10 @@ liboqs_la_LIBADD += src/kex_ntru/libntru.la
|
||||
liboqs_la_LIBADD += external/NTRUEncrypt-master/.libs/libntruencrypt.la
|
||||
endif
|
||||
|
||||
if USE_SIDH_IQC
|
||||
liboqs_la_LIBADD += src/kex_sidh_iqc_ref/libsidhiqc.la
|
||||
endif
|
||||
|
||||
noinst_bin_PROGRAMS = test_rand test_kex test_aes
|
||||
noinst_bindir=$(prefix)/tests
|
||||
test_kex_LDADD = liboqs.la -lm
|
||||
@ -42,6 +46,9 @@ endif
|
||||
if USE_MCBITS
|
||||
test_kex_LDADD += -lsodium
|
||||
endif
|
||||
if USE_SIDH_IQC
|
||||
test_kex_LDADD += -lgmp
|
||||
endif
|
||||
|
||||
test_aes_LDADD = liboqs.la -lm
|
||||
test_aes_SOURCES = src/crypto/aes/test_aes.c
|
||||
@ -101,6 +108,10 @@ endif
|
||||
if USE_NTRU
|
||||
$(LN_S) -f ../../src/kex_ntru/kex_ntru.h include/oqs
|
||||
endif
|
||||
if USE_SIDH_IQC
|
||||
$(LN_S) -f ../../src/kex_sidh_iqc_ref/kex_sidh_iqc_ref.h include/oqs
|
||||
$(LN_S) -f src/kex_sidh_iqc_ref/sample_params
|
||||
endif
|
||||
|
||||
clean-local:
|
||||
rm -f liboqs.a
|
||||
|
19
configure.ac
19
configure.ac
@ -69,14 +69,19 @@ ARG_ENABL_SET([ntru], [enable NTRU.])
|
||||
AM_CONDITIONAL([ntru], [test "x$ntru" = xtrue])
|
||||
AM_CONDITIONAL([USE_NTRU], [test "x$ntru" = xtrue])
|
||||
|
||||
ARG_ENABL_SET([sidhiqc], [enable SIDH-IQC.])
|
||||
AM_CONDITIONAL([sidhiqc], [test "x$sidhiqc" = xtrue])
|
||||
AM_CONDITIONAL([USE_SIDH_IQC], [test "x$sidhiqc" = xtrue])
|
||||
|
||||
AM_CPPFLAGS="-O3 -std=gnu11 -Wpedantic -Wall -Wextra -DCONSTANT_TIME"
|
||||
|
||||
AM_CPPFLAGS="-g -std=gnu11 -Wpedantic -Wall -Wextra -DCONSTANT_TIME"
|
||||
AC_CANONICAL_HOST
|
||||
# Check for which host we are on and setup a few things
|
||||
# specifically based on the host
|
||||
case $host_os in
|
||||
darwin* )
|
||||
OPENSSL_DIR=/usr/local/opt/openssl
|
||||
GMP_DIR=/usr/local/opt/include
|
||||
AM_CONDITIONAL([ON_DARWIN], [test xtrue = xtrue])
|
||||
;;
|
||||
linux*)
|
||||
@ -92,7 +97,6 @@ case $host_os in
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
SRCDIR=" src/common src/crypto/aes src/kex src/crypto/rand src/crypto/sha3"
|
||||
SRCDIR=${SRCDIR}" src/crypto/rand_urandom_aesctr src/crypto/rand_urandom_chacha20"
|
||||
SRCDIR=${SRCDIR}" src/kex_rlwe_bcns15/"
|
||||
@ -101,8 +105,6 @@ SRCDIR=${SRCDIR}" src/kex_lwe_frodo"
|
||||
SRCDIR=${SRCDIR}" src/kex_rlwe_msrln16"
|
||||
SRCDIR=${SRCDIR}" src/kex_sidh_cln16"
|
||||
|
||||
|
||||
|
||||
if test x"$ntru" = x"true"; then
|
||||
AM_CPPFLAGS=${AM_CPPFLAGS}" -DENABLE_NTRU"
|
||||
SRCDIR=${SRCDIR}" src/kex_ntru"
|
||||
@ -121,6 +123,12 @@ if test x"$openssl" = x"true"; then
|
||||
AM_CPPFLAGS=${AM_CPPFLAGS}" -DUSE_OPENSSL"
|
||||
fi
|
||||
|
||||
if test x"$sidhiqc" = x"true"; then
|
||||
AM_CPPFLAGS=${AM_CPPFLAGS}" -DENABLE_SIDH_IQC_REF"
|
||||
SRCDIR=${SRCDIR}" src/kex_sidh_iqc_ref"
|
||||
fi
|
||||
|
||||
|
||||
AC_SUBST(AM_CPPFLAGS)
|
||||
AC_SUBST(SRCDIR)
|
||||
AC_SUBST(OPENSSL_DIR)
|
||||
@ -128,7 +136,9 @@ AC_SUBST(USE_OPENSSL)
|
||||
AC_SUBST(USE_AES_NI)
|
||||
AC_SUBST(USE_NTRU)
|
||||
AC_SUBST(USE_MCBITS)
|
||||
AC_SUBST(USE_SIDH_IQC)
|
||||
AC_SUBST(ON_DARWIN)
|
||||
AC_SUBST(GMP_DIR)
|
||||
|
||||
|
||||
AC_CONFIG_FILES([Makefile
|
||||
@ -145,6 +155,7 @@ AC_CONFIG_FILES([Makefile
|
||||
src/kex_sidh_cln16/Makefile
|
||||
src/kex_code_mcbits/Makefile
|
||||
src/kex_ntru/Makefile
|
||||
src/kex_sidh_iqc_ref/Makefile
|
||||
src/kex_lwe_frodo/Makefile])
|
||||
|
||||
AC_OUTPUT
|
||||
|
@ -14,6 +14,7 @@
|
||||
#ifdef ENABLE_NTRU
|
||||
#include <oqs/kex_ntru.h>
|
||||
#endif
|
||||
#include <oqs/kex_sidh_iqc_ref.h>
|
||||
|
||||
OQS_KEX *OQS_KEX_new(OQS_RAND *rand, enum OQS_KEX_alg_name alg_name, const uint8_t *seed, const size_t seed_len, const char *named_parameters) {
|
||||
switch (alg_name) {
|
||||
@ -43,6 +44,12 @@ OQS_KEX *OQS_KEX_new(OQS_RAND *rand, enum OQS_KEX_alg_name alg_name, const uint8
|
||||
#else
|
||||
assert(0);
|
||||
#endif
|
||||
case OQS_KEX_alg_sidh_iqc_ref:
|
||||
#ifdef ENABLE_SIDH_IQC_REF
|
||||
return OQS_KEX_sidh_iqc_ref_new(rand);
|
||||
#else
|
||||
assert(0);
|
||||
#endif
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
|
@ -20,6 +20,7 @@ enum OQS_KEX_alg_name {
|
||||
OQS_KEX_alg_sidh_cln16,
|
||||
OQS_KEX_alg_code_mcbits,
|
||||
OQS_KEX_alg_ntru,
|
||||
OQS_KEX_alg_sidh_iqc_ref,
|
||||
};
|
||||
|
||||
typedef struct OQS_KEX OQS_KEX;
|
||||
|
@ -25,6 +25,9 @@ struct kex_testcase kex_testcases[] = {
|
||||
{OQS_KEX_alg_rlwe_msrln16, NULL, 0, NULL, "rlwe_msrln16", 0, 100},
|
||||
{OQS_KEX_alg_lwe_frodo, (unsigned char *) "01234567890123456", 16, "recommended", "lwe_frodo_recommended", 0, 100},
|
||||
{OQS_KEX_alg_sidh_cln16, NULL, 0, NULL, "sidh_cln16", 0, 10},
|
||||
#ifdef ENABLE_SIDH_IQC_REF
|
||||
{OQS_KEX_alg_sidh_iqc_ref, NULL, 0, NULL, "sidh_iqc_ref", 0, 10},
|
||||
#endif
|
||||
#ifdef ENABLE_CODE_MCBITS
|
||||
{OQS_KEX_alg_code_mcbits, NULL, 0, NULL, "code_mcbits", 0, 25},
|
||||
#endif
|
||||
|
10
src/kex_sidh_iqc_ref/Makefile.am
Normal file
10
src/kex_sidh_iqc_ref/Makefile.am
Normal file
@ -0,0 +1,10 @@
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
noinst_LTLIBRARIES = libsidhiqc.la
|
||||
|
||||
|
||||
libsidhiqc_la_SOURCES = kex_sidh_iqc_ref.c sidh_elliptic_curve.c sidh_elliptic_curve_dlp.c sidh_isogeny.c
|
||||
libsidhiqc_la_SOURCES += sidh_private_key.c sidh_public_key.c sidh_public_key_encryption.c sidh_public_key_validation.c
|
||||
libsidhiqc_la_SOURCES += sidh_public_param.c sidh_quadratic_ext.c sidh_shared_key.c sidh_util.c
|
||||
libsidhiqc_la_CPPFLAGS = -I../../include -I.-fPIC
|
||||
libsidhiqc_la_CPPFLAGS += $(AM_CPPFLAGS) -I$(GMP_DIR)
|
||||
|
208
src/kex_sidh_iqc_ref/kex_sidh_iqc_ref.c
Normal file
208
src/kex_sidh_iqc_ref/kex_sidh_iqc_ref.c
Normal file
@ -0,0 +1,208 @@
|
||||
#if defined(WINDOWS)
|
||||
#define UNUSED
|
||||
#else
|
||||
#define UNUSED __attribute__((unused))
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "sidh_elliptic_curve.h"
|
||||
#include "sidh_public_param.h"
|
||||
#include "sidh_isogeny.h"
|
||||
#include "sidh_private_key.h"
|
||||
#include "sidh_public_key.h"
|
||||
#include "sidh_shared_key.h"
|
||||
#include "kex_sidh_iqc_ref.h"
|
||||
|
||||
OQS_KEX *OQS_KEX_sidh_iqc_ref_new(OQS_RAND *rand) {
|
||||
|
||||
OQS_KEX *k = malloc(sizeof(OQS_KEX));
|
||||
if (k == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// initialize
|
||||
// char *input_params = "sample_params/public_params_771";
|
||||
public_params_t *params =
|
||||
(public_params_t *) malloc(2 * sizeof(public_params_t));
|
||||
oqs_sidh_iqc_ref_public_params_init(params[0]);
|
||||
oqs_sidh_iqc_ref_public_params_init(params[1]);
|
||||
|
||||
if (!oqs_sidh_iqc_ref_public_params_read(params[0], params[1], "sample_params/public_params_771"))
|
||||
return NULL;
|
||||
|
||||
oqs_sidh_iqc_ref_fp_init_chararacteristic(params[0]->characteristic);
|
||||
|
||||
k->rand = rand;
|
||||
k->method_name = strdup("SIDH IQC REFERENCE");
|
||||
k->estimated_classical_security = 192;
|
||||
k->estimated_quantum_security = 128;
|
||||
k->seed = NULL;
|
||||
k->seed_len = 0;
|
||||
k->named_parameters = strdup("sample_params/public_params_771");
|
||||
k->params = params;
|
||||
k->ctx = NULL;
|
||||
k->alice_0 = &OQS_KEX_sidh_iqc_ref_alice_0;
|
||||
k->bob = &OQS_KEX_sidh_iqc_ref_bob;
|
||||
k->alice_1 = &OQS_KEX_sidh_iqc_ref_alice_1;
|
||||
k->alice_priv_free = &OQS_KEX_sidh_iqc_ref_alice_priv_free;
|
||||
k->free = &OQS_KEX_sidh_iqc_ref_free;
|
||||
|
||||
return k;
|
||||
}
|
||||
|
||||
int OQS_KEX_sidh_iqc_ref_alice_0(OQS_KEX *k, void **alice_priv,
|
||||
uint8_t **alice_msg, size_t *alice_msg_len) {
|
||||
|
||||
public_params_t *params = (public_params_t *) k->params;
|
||||
private_key_t Alice_private_key;
|
||||
oqs_sidh_iqc_ref_private_key_init(Alice_private_key);
|
||||
oqs_sidh_iqc_ref_private_key_generate(Alice_private_key, params[0]);
|
||||
|
||||
public_key_t Alice_public_key;
|
||||
oqs_sidh_iqc_ref_public_key_init(Alice_public_key);
|
||||
point_t kernel_gen;
|
||||
oqs_sidh_iqc_ref_point_init(kernel_gen);
|
||||
oqs_sidh_iqc_ref_private_key_compute_kernel_gen(kernel_gen, Alice_private_key,
|
||||
params[0]->P, params[0]->Q,
|
||||
params[0]->le, params[0]->E);
|
||||
oqs_sidh_iqc_ref_public_key_generate(Alice_public_key, kernel_gen, params[0],
|
||||
params[1]);
|
||||
|
||||
// sizes in bytes
|
||||
uint32_t prime_size = (mpz_sizeinbase(characteristic, 2) + 7) / 8;
|
||||
uint32_t private_key_size = 2 * prime_size;
|
||||
uint32_t public_key_size = 12 * prime_size;
|
||||
|
||||
*alice_priv = NULL;
|
||||
*alice_msg = NULL;
|
||||
*alice_priv = malloc(private_key_size);
|
||||
*alice_msg = malloc(public_key_size);
|
||||
*alice_msg_len = public_key_size;
|
||||
|
||||
oqs_sidh_iqc_ref_private_key_to_bytes((uint8_t *) *alice_priv,
|
||||
Alice_private_key, prime_size);
|
||||
oqs_sidh_iqc_ref_public_key_to_bytes((uint8_t *) *alice_msg, Alice_public_key,
|
||||
prime_size);
|
||||
|
||||
oqs_sidh_iqc_ref_private_key_clear(Alice_private_key);
|
||||
oqs_sidh_iqc_ref_public_key_clear(Alice_public_key);
|
||||
oqs_sidh_iqc_ref_point_clear(kernel_gen);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int OQS_KEX_sidh_iqc_ref_bob(OQS_KEX *k, const uint8_t *alice_msg,
|
||||
UNUSED const size_t alice_msg_len,
|
||||
uint8_t **bob_msg, size_t *bob_msg_len,
|
||||
uint8_t **key, size_t *key_len) {
|
||||
|
||||
public_params_t *params = (public_params_t *) k->params;
|
||||
|
||||
private_key_t Bob_private_key;
|
||||
oqs_sidh_iqc_ref_private_key_init(Bob_private_key);
|
||||
oqs_sidh_iqc_ref_private_key_generate(Bob_private_key, params[1]);
|
||||
|
||||
public_key_t Bob_public_key;
|
||||
oqs_sidh_iqc_ref_public_key_init(Bob_public_key);
|
||||
point_t kernel_gen;
|
||||
oqs_sidh_iqc_ref_point_init(kernel_gen);
|
||||
oqs_sidh_iqc_ref_private_key_compute_kernel_gen(kernel_gen, Bob_private_key,
|
||||
params[1]->P, params[1]->Q,
|
||||
params[1]->le, params[1]->E);
|
||||
oqs_sidh_iqc_ref_public_key_generate(Bob_public_key, kernel_gen, params[1],
|
||||
params[0]);
|
||||
|
||||
// sizes in bytes
|
||||
uint32_t prime_size = (mpz_sizeinbase(characteristic, 2) + 7) / 8;
|
||||
uint32_t public_key_size = 12 * prime_size;
|
||||
uint32_t shared_key_size = 2 * prime_size;
|
||||
|
||||
*bob_msg = NULL;
|
||||
*key = NULL;
|
||||
*bob_msg = malloc(public_key_size);
|
||||
*key = malloc(shared_key_size);
|
||||
*bob_msg_len = public_key_size;
|
||||
*key_len = shared_key_size;
|
||||
|
||||
oqs_sidh_iqc_ref_public_key_to_bytes((uint8_t *) *bob_msg, Bob_public_key,
|
||||
prime_size);
|
||||
|
||||
public_key_t Alice_public_key;
|
||||
oqs_sidh_iqc_ref_public_key_init(Alice_public_key);
|
||||
oqs_sidh_iqc_ref_bytes_to_public_key(Alice_public_key, alice_msg, prime_size);
|
||||
|
||||
fp2_element_t Bob_shared_key;
|
||||
oqs_sidh_iqc_ref_fp2_init(Bob_shared_key);
|
||||
oqs_sidh_iqc_ref_shared_key_generate(Bob_shared_key, Alice_public_key,
|
||||
Bob_private_key, params[1]);
|
||||
|
||||
oqs_sidh_iqc_ref_fp2_to_bytes((uint8_t *) *key, Bob_shared_key, prime_size);
|
||||
|
||||
oqs_sidh_iqc_ref_public_key_clear(Alice_public_key);
|
||||
oqs_sidh_iqc_ref_private_key_clear(Bob_private_key);
|
||||
oqs_sidh_iqc_ref_public_key_clear(Bob_public_key);
|
||||
oqs_sidh_iqc_ref_point_clear(kernel_gen);
|
||||
oqs_sidh_iqc_ref_fp2_clear(Bob_shared_key);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int OQS_KEX_sidh_iqc_ref_alice_1(OQS_KEX *k, const void *alice_priv,
|
||||
const uint8_t *bob_msg,
|
||||
UNUSED const size_t bob_msg_len, uint8_t **key,
|
||||
size_t *key_len) {
|
||||
|
||||
public_params_t *params = (public_params_t *) k->params;
|
||||
|
||||
// sizes in bytes
|
||||
uint32_t prime_size = (mpz_sizeinbase(characteristic, 2) + 7) / 8;
|
||||
uint32_t shared_key_size = 2 * prime_size;
|
||||
|
||||
*key = NULL;
|
||||
*key_len = shared_key_size;
|
||||
*key = malloc(shared_key_size);
|
||||
|
||||
private_key_t Alice_private_key;
|
||||
oqs_sidh_iqc_ref_private_key_init(Alice_private_key);
|
||||
oqs_sidh_iqc_ref_bytes_to_private_key(Alice_private_key, alice_priv,
|
||||
prime_size);
|
||||
|
||||
public_key_t Bob_public_key;
|
||||
oqs_sidh_iqc_ref_public_key_init(Bob_public_key);
|
||||
oqs_sidh_iqc_ref_bytes_to_public_key(Bob_public_key, bob_msg, prime_size);
|
||||
|
||||
fp2_element_t Alice_shared_key;
|
||||
oqs_sidh_iqc_ref_fp2_init(Alice_shared_key);
|
||||
oqs_sidh_iqc_ref_shared_key_generate(Alice_shared_key, Bob_public_key,
|
||||
Alice_private_key, params[0]);
|
||||
|
||||
oqs_sidh_iqc_ref_fp2_to_bytes((uint8_t *) *key, Alice_shared_key, prime_size);
|
||||
|
||||
oqs_sidh_iqc_ref_private_key_clear(Alice_private_key);
|
||||
oqs_sidh_iqc_ref_public_key_clear(Bob_public_key);
|
||||
oqs_sidh_iqc_ref_fp2_clear(Alice_shared_key);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void OQS_KEX_sidh_iqc_ref_alice_priv_free(UNUSED OQS_KEX *k, void *alice_priv) {
|
||||
if (alice_priv) {
|
||||
free(alice_priv);
|
||||
}
|
||||
}
|
||||
|
||||
void OQS_KEX_sidh_iqc_ref_free(OQS_KEX *k) {
|
||||
if (!k) {
|
||||
return;
|
||||
}
|
||||
|
||||
oqs_sidh_iqc_ref_public_params_clear(((public_params_t *) (k->params))[0]);
|
||||
oqs_sidh_iqc_ref_public_params_clear(((public_params_t *) (k->params))[1]);
|
||||
free(k->params);
|
||||
k->ctx = NULL;
|
||||
free(k->method_name);
|
||||
k->method_name = NULL;
|
||||
free(k);
|
||||
}
|
28
src/kex_sidh_iqc_ref/kex_sidh_iqc_ref.h
Normal file
28
src/kex_sidh_iqc_ref/kex_sidh_iqc_ref.h
Normal file
@ -0,0 +1,28 @@
|
||||
|
||||
#ifndef KEX_SIDH_IQC_REF_H
|
||||
#define KEX_SIDH_IQC_REF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <oqs/kex.h>
|
||||
#include <oqs/rand.h>
|
||||
|
||||
OQS_KEX *OQS_KEX_sidh_iqc_ref_new(OQS_RAND *rand);
|
||||
|
||||
int OQS_KEX_sidh_iqc_ref_alice_0(OQS_KEX *k, void **alice_priv, uint8_t **alice_msg, size_t *alice_msg_len);
|
||||
int OQS_KEX_sidh_iqc_ref_bob(OQS_KEX *k, const uint8_t *alice_msg, const size_t alice_msg_len, uint8_t **bob_msg, size_t *bob_msg_len, uint8_t **key, size_t *key_len);
|
||||
int OQS_KEX_sidh_iqc_ref_alice_1(OQS_KEX *k, const void *alice_priv, const uint8_t *bob_msg, const size_t bob_msg_len, uint8_t **key, size_t *key_len);
|
||||
|
||||
void OQS_KEX_sidh_iqc_ref_alice_priv_free(OQS_KEX *k, void *alice_priv);
|
||||
void OQS_KEX_sidh_iqc_ref_free(OQS_KEX *k);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* KEX_SIDH_IQC_REF_H */
|
10
src/kex_sidh_iqc_ref/sample_params/public_params_263
Normal file
10
src/kex_sidh_iqc_ref/sample_params/public_params_263
Normal file
@ -0,0 +1,10 @@
|
||||
p : 13278338917780691403163453935679248163066204141424819568321422575495838416502783
|
||||
E : y^2 = x^3 + (10146232096640085910917654383121220722483913358884738813297160334128811466415525*i+12561065565697579851239386918801659303795666601356542822684985096240783059294353)*x + (5173097881985929355869345579251684505584624561073144550698251610858120795396524*i+7107679418274528586696192790945059679329002947961173384005281572895084003568218)
|
||||
lA: 2
|
||||
eA: 130
|
||||
PA: (1195124728519659060317276132092013999345554256425666367370465963951595701748339*i + 12098972036709468461769702810131237350914726908853501736574286596252384974205652, 9783772475920257416467468866150378267376245694752823265285613818169901942309758*i + 11347159712348451494564706572599934965946403356550033502368700150470499448870987)
|
||||
QA: (13205817885805264818436305084890835188490919868599289846511015770901764583677253*i + 5747572646648472262100078852868099320898697620053049578554081522615552834142382, 11801682343040573989191884352262922625922977024975963745404870899756844108073781*i + 995065035530346107238957276796927946979246210950956147759509023538740100220494)
|
||||
lB: 3
|
||||
eB: 81
|
||||
PB: (5344800255669587458309912385997503623935901519546261901204157001079956379346933*i + 4377688844822469620769951245537289173274736372423169606270308984109645753298367, 6652276474756696057821879367411351758786745790244544252917780253177388224676512*i + 6708409928090950067466623637647088247028372838873736207829979327577754417492323)
|
||||
QB: (5394161621076087291764603321428338049084294313968048256313378341079709241759382*i + 11839282739753708776384780179031575074752559110018400195581350405443930573103478, 13250321748367194013481592159238890438519376028036613608154243555537109237538486*i + 5018156126061581597984382235576466750307112019427938373002833669914648135622879)
|
10
src/kex_sidh_iqc_ref/sample_params/public_params_46
Normal file
10
src/kex_sidh_iqc_ref/sample_params/public_params_46
Normal file
@ -0,0 +1,10 @@
|
||||
p : 60183678025727
|
||||
E : y^2 = x^3 + (33377407586757 * i + 44218433491776) * x + (14267804413813 * i + 34113052821919)
|
||||
lA: 2
|
||||
eA: 22
|
||||
PA: (3621292231555 * i + 37993208494088, 7444041801194 * i + 49342879615307)
|
||||
QA: (42474562877393 * i + 53371276514445, 2096833973245 * i + 34935006825293)
|
||||
lB: 3
|
||||
eB: 15
|
||||
PB: (15834791163149 * i + 48632673242917, 26787723276578 * i + 2080970701160)
|
||||
QB: (41347477823487 * i + 16893996428645, 16353006256863 * i + 58871308637793)
|
10
src/kex_sidh_iqc_ref/sample_params/public_params_521
Normal file
10
src/kex_sidh_iqc_ref/sample_params/public_params_521
Normal file
@ -0,0 +1,10 @@
|
||||
p : 5646428529833603710854376801719732121889771686125102421349898409102848702003905102057129871853579459735758942656769724874115169484320460874488881525976727551
|
||||
E : y^2 = x^3 + (749284552715987846148963973296050195126229569341142224654666772427960869882697237787535113296933915107646826510805251959952317725821624926383192023779227916*i+4450862168665197219135947325665108840719206715065697554561201799074300990784248608236935291171911258967881216685164820345027022153809546719817771293646383402)*x + (2090701186560231235295975659537182225064154823783034367876346818451609525370628921026656891712603865222854303410638520367213822274197422708317359681412801686*i+928331116130151780314451251635374082476545231185861659046556547242876069870814548070746611568992085667981514874929668958586384832118048434225604407758374282)
|
||||
lA: 2
|
||||
eA: 258
|
||||
PA: (4099566244205693793351119863629118684504739011975746402268940060566068632610815266810397027797757094816929218567651253950072216325440815687610023993835084896*i + 1558017772998619899443036875935946235185689333987633624537644882488763783158554538347022310514300405167644627965823931934377803788161014061154800653636626931, 4309963503463625615680726988334053841208952164733703323705989592325431854359074218382917880219717866947948218257035199142577782828393068620191995480863080814*i + 371139087724151319343471759858355552237686119972572871121509307705868621618190178855645217401101942092226237837619601742237974591506374361483536984282167861)
|
||||
QA: (1068668697541208179714192612921089347931894414290359842562082470165052062241629674686530102495737378212525479245784252461983051355518227298502808569246918728*i + 3439758296201500299118396242846510199830393172149382335887091564620130903972985332523718369650346601985540123834734249105539074407495456634862920938577617312, 1377114633894100174167466575056453645918713530999472681191914854993325497527119824352424425031078252594689770391880104513192317018010057467691025379460070671*i + 4932622986840321005380766859714312144000718130204073302754586852541324804616229501269099878044960212632820224170853684078869359092914886360672352750928115581)
|
||||
lB: 3
|
||||
eB: 161
|
||||
PB: (1873601143875829767876930991819826178988629054425671567488176037109831662817961473686026144306947256312476316751547084289880741326649856082832561714610850944*i + 1560175318533519875886314144935322002014985257654221707041583923868859979591849198401249634353361077499233198751747045058302746944304448268907689086502178616, 4982994975025169124121736752171094366264972439763192439008272414941290947933013927951198144521578535758162978083130741822789277050594650669549067865269480720*i + 5276260709601376725929198456951440724276715138987805447686932240717621617089316893818094566900580557346731678327745302440662762271627385800896501795127323769)
|
||||
QB: (697646709404910236660735870475422491121726200391885074740251760174191839071888445718446637282034941836922171390196797602747505117748596104805560163856490804*i + 3625576702015594834652275264908614642470435266304155762812699923280767886451566560460365242828862442624975825786369269113406701427398318872227046324990780609, 4066773540363717441440268891591433184568174886592697891244632377954091519594774358483000191238791345767299029423088482812653880802118173619454377886226640626*i + 4190003034380720563592676434553383980850520959077934081654167677748426947392920518786394581045699661017779519240551462796264093681413592624709890262004623150)
|
11
src/kex_sidh_iqc_ref/sample_params/public_params_771
Normal file
11
src/kex_sidh_iqc_ref/sample_params/public_params_771
Normal file
@ -0,0 +1,11 @@
|
||||
p : 9161191555982008052298538759697325872858383005444503030763917191888120427263653604739574602371851919945332710234806205297475768266460658683484318356498713773944703702864057467786913144364234277796785269800198817400814717913480036351
|
||||
E : y^2 = x^3 + (834414288954992257633455994192711449929625512434805347027412475310171948875352369017186937444645005409828817983476510572586689796723205608064400704385270116308944492168385499542550868452776212626111499661118550170888024552876875729*i+6422246000772528873002015578224375300444670334298744905928223359513938843110113655634334268879522218663819121887750824098836054966064056104287198717041277477329053582144813207672147369924203318339728355843554541603191165928512397074)*x + (6952862402661321818296934608460489441319492072429008834217170925899505712694617760090534612163651714423387662001257443691685988562319647888954263195545834510820670121276853179853453135161349568882745925527747286264586000816122662211*i+1801461307959256058754493292728237821856779795303869606357346421878164668617118529630863155614277813374785952465141324739461376333648338471745996274618770379494305097783365807731152848487472399799827998470890201827624741461111844749)
|
||||
lA: 2
|
||||
eA: 386
|
||||
PA: (8104593598414300086705087098908311675030394399959710332294184564762361863835814307651327024806690095568546280563692186849608460564606528773115207348687739021740029922619947714003573784888374548470687911506820492526985145356335776446*i + 632723349492681895135768435670357424582748082370711990704098097526814363254991414123449305576539513413267774301605548017161074510859073483979044361740779150098452314120335316096416597425252882878881588818896781804191220848731008911, 6034454472695438020325443031188950458345445112930585331722482288319997086142640364760979210290700670085317874428427766978327706213014073448960161802245001428613528860063394247112544226096847944993689243523414240839321526974724280084*i + 3376800547075148066131970733541260743185153743453912100162319249600572606491084521062090319658073231669236186390422247468127880255567740549554667385892315318084299520660699776774656198376921140804260118165199828142540405774846853362)
|
||||
QA: (2765053530820933445180998871832795313413946616218824127593215418859013295660994609348273546952174346166291903038023352135058779784133949653750586420316372475215070348272866065120539728715859798970386824706592072979142529191135265323*i + 4732630024306258879927225136904171174931421517225731042645253305380470569884989406374249571295113204909266761424593068942210539695621294791558555039840356194123377363470161894673618251481432584334320864233790205509164494505329331140, 4708584843807409676003733183136845288008597122413250473476957203240325041335536376819164132204831789648003763063194049792870695914267484368767687682889171445457695974399304884657394666807097601382128550039198416659937221320896980595*i + 6104437072476030203734870744361913380396342850775889826642334399814339224961644051070388756974954400647041041004040997989961961816982978689836414675142946310418861822777207486737128660492374354598010889893873060781304652392500710082)
|
||||
lB: 3
|
||||
eB: 242
|
||||
PB: (3723895349260758944309889666952259909100424286764560948312844268916772080039091215194337476636106420561414206591006321840112505108525982835492286766266110460566937541551059011352798312867785900902951383836578444811900436603779674156*i + 8743733696371247709279217014221258693400652288884395784267041686740452975091187425123471886102340505926375682973850553993788314479705338557349284829716634286210825839825870379330100097103593148671390855900137936801780665161878467993, 8424241650394632026078421716292833598872223719053431149109783663376931645995151278886785513466077121063748132909299925706619410172763350254899661370368971798311266097772796416940961537063436478392108549760549489321636110323643921123*i + 5374610701506876802640722880318277643810083668249556787469960695884056089879250039154916755196748541850985290281804798435130927222521567170894905772855374873224510597225929994186728464447646660504589278345473514974074045904197344273)
|
||||
QB: (7981195513789185488304157075392399068225052449489399943063249773724560281912789833792310612686835775356813196319643714519912123781500389027567621573946130157326769787082613646934296091151487953874493791717298439146548339580934348575*i + 6959299245778867305112554827985507377113662771316265280990751282080086185858550157506531552361757479904416443825479048359163719118671413144273420888615839877660288012435298448942304481059091585291706567711227879486375625133765783910, 4336888647745442057861067196613721067586889048321014506728806821392030059558638097842307835657146159647787621123250859783441147632121339894258934458102109985684014691372520469809743302874968486912740925764328254939284436994206821845*i + 219245698132319235934495637714582743670714862281024333766283207034829039474459867538486706426384326703893620364910932534607493596118208826082598798090838576408297983032654112984263431060439529497966028364279027386883785406090014775)
|
||||
|
368
src/kex_sidh_iqc_ref/sidh_elliptic_curve.c
Normal file
368
src/kex_sidh_iqc_ref/sidh_elliptic_curve.c
Normal file
@ -0,0 +1,368 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "sidh_elliptic_curve.h"
|
||||
#include "sidh_util.h"
|
||||
#include <string.h>
|
||||
|
||||
void oqs_sidh_iqc_ref_elliptic_curve_init(elliptic_curve_t E) {
|
||||
oqs_sidh_iqc_ref_fp2_init_set_si(E->a, 0, 1);
|
||||
oqs_sidh_iqc_ref_fp2_init_set_si(E->b, 0, 1);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_elliptic_curve_set(elliptic_curve_t E,
|
||||
const elliptic_curve_t T) {
|
||||
oqs_sidh_iqc_ref_fp2_set(E->a, T->a);
|
||||
oqs_sidh_iqc_ref_fp2_set(E->b, T->b);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_elliptic_curve_set_coeffs(elliptic_curve_t E,
|
||||
const fp2_element_t a,
|
||||
const fp2_element_t b) {
|
||||
oqs_sidh_iqc_ref_fp2_set(E->a, a);
|
||||
oqs_sidh_iqc_ref_fp2_set(E->b, b);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_point_init(point_t P) {
|
||||
oqs_sidh_iqc_ref_fp2_init(P->x);
|
||||
oqs_sidh_iqc_ref_fp2_init(P->y);
|
||||
oqs_sidh_iqc_ref_point_zero(P);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_point_set_coordinates(point_t P,
|
||||
const fp2_element_t x,
|
||||
const fp2_element_t y,
|
||||
int z) {
|
||||
oqs_sidh_iqc_ref_fp2_set(P->x, x);
|
||||
oqs_sidh_iqc_ref_fp2_set(P->y, y);
|
||||
P->z = z;
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_point_set(point_t P,
|
||||
const point_t Q) {
|
||||
oqs_sidh_iqc_ref_point_set_coordinates(P, Q->x, Q->y, Q->z);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_point_zero(point_t P) {
|
||||
oqs_sidh_iqc_ref_fp2_zero(P->x);
|
||||
oqs_sidh_iqc_ref_fp2_one(P->y);
|
||||
P->z = 0;
|
||||
}
|
||||
|
||||
int oqs_sidh_iqc_ref_point_is_zero(const point_t P) {
|
||||
return P->z == 0;
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_point_negate(point_t P,
|
||||
const point_t Q) {
|
||||
oqs_sidh_iqc_ref_point_set(P, Q);
|
||||
oqs_sidh_iqc_ref_fp2_negate(P->y, P->y);
|
||||
}
|
||||
|
||||
int oqs_sidh_iqc_ref_point_has_order_2(const point_t P) {
|
||||
return oqs_sidh_iqc_ref_fp2_is_zero(P->y);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_elliptic_curve_clear(elliptic_curve_t E) {
|
||||
oqs_sidh_iqc_ref_fp2_clear(E->a);
|
||||
oqs_sidh_iqc_ref_fp2_clear(E->b);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_point_clear(point_t P) {
|
||||
oqs_sidh_iqc_ref_fp2_clear(P->x);
|
||||
oqs_sidh_iqc_ref_fp2_clear(P->y);
|
||||
}
|
||||
|
||||
int oqs_sidh_iqc_ref_point_equals(const point_t P,
|
||||
const point_t Q) {
|
||||
return oqs_sidh_iqc_ref_fp2_equals(P->x, Q->x) &&
|
||||
oqs_sidh_iqc_ref_fp2_equals(P->y, Q->y) &&
|
||||
(P->z == Q->z);
|
||||
}
|
||||
|
||||
char *oqs_sidh_iqc_ref_elliptic_curve_get_str(const elliptic_curve_t E) {
|
||||
char *result = "";
|
||||
result = oqs_sidh_iqc_ref_concat(result, "y^2 = x^3");
|
||||
if (!oqs_sidh_iqc_ref_fp2_is_zero(E->a)) {
|
||||
result = oqs_sidh_iqc_ref_concat(result, " + (");
|
||||
result = oqs_sidh_iqc_ref_concat(result, oqs_sidh_iqc_ref_fp2_get_str(E->a));
|
||||
result = oqs_sidh_iqc_ref_concat(result, ")");
|
||||
result = oqs_sidh_iqc_ref_concat(result, " * x");
|
||||
}
|
||||
|
||||
if (!oqs_sidh_iqc_ref_fp2_is_zero(E->b)) {
|
||||
result = oqs_sidh_iqc_ref_concat(result, " + (");
|
||||
result = oqs_sidh_iqc_ref_concat(result, oqs_sidh_iqc_ref_fp2_get_str(E->b));
|
||||
result = oqs_sidh_iqc_ref_concat(result, ")");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
char *oqs_sidh_iqc_ref_point_get_str(const point_t P) {
|
||||
char *result = "";
|
||||
result = oqs_sidh_iqc_ref_concat(result, "(");
|
||||
result = oqs_sidh_iqc_ref_concat(result, oqs_sidh_iqc_ref_fp2_get_str(P->x));
|
||||
result = oqs_sidh_iqc_ref_concat(result, " : ");
|
||||
result = oqs_sidh_iqc_ref_concat(result, oqs_sidh_iqc_ref_fp2_get_str(P->y));
|
||||
result = oqs_sidh_iqc_ref_concat(result, " : ");
|
||||
result = oqs_sidh_iqc_ref_concat(result, (P->z == 1 ? "1" : "0"));
|
||||
result = oqs_sidh_iqc_ref_concat(result, ")");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_point_add_with_lambda(point_t R,
|
||||
const point_t P,
|
||||
const point_t Q,
|
||||
const fp2_element_t lambda) {
|
||||
point_t result;
|
||||
oqs_sidh_iqc_ref_point_init(result);
|
||||
result->z = 1;
|
||||
|
||||
// x_R = lambda^2 - x_P - x_Q
|
||||
oqs_sidh_iqc_ref_fp2_square(result->x, lambda);
|
||||
oqs_sidh_iqc_ref_fp2_sub(result->x, result->x, P->x);
|
||||
oqs_sidh_iqc_ref_fp2_sub(result->x, result->x, Q->x);
|
||||
|
||||
// y_R = lambda * (x_P - x_R) - y_P
|
||||
oqs_sidh_iqc_ref_fp2_sub(result->y, P->x, result->x);
|
||||
oqs_sidh_iqc_ref_fp2_mul(result->y, result->y, lambda);
|
||||
oqs_sidh_iqc_ref_fp2_sub(result->y, result->y, P->y);
|
||||
oqs_sidh_iqc_ref_point_set(R, result);
|
||||
|
||||
oqs_sidh_iqc_ref_point_clear(result);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_point_double(point_t R,
|
||||
const point_t P,
|
||||
const elliptic_curve_t E) {
|
||||
if (oqs_sidh_iqc_ref_point_is_zero(P)) {
|
||||
oqs_sidh_iqc_ref_point_zero(R);
|
||||
return;
|
||||
}
|
||||
|
||||
// check if the point is of order 2
|
||||
if (oqs_sidh_iqc_ref_point_has_order_2(P)) {
|
||||
oqs_sidh_iqc_ref_point_zero(R);
|
||||
return;
|
||||
}
|
||||
|
||||
fp2_element_t temp;
|
||||
fp2_element_t lambda;
|
||||
|
||||
oqs_sidh_iqc_ref_fp2_init(temp);
|
||||
oqs_sidh_iqc_ref_fp2_init(lambda);
|
||||
|
||||
// lambda = (3(x_P)^2 + a) / (2y_p)
|
||||
oqs_sidh_iqc_ref_fp2_square(lambda, P->x);
|
||||
oqs_sidh_iqc_ref_fp2_mul_scaler_si(lambda, lambda, 3);
|
||||
oqs_sidh_iqc_ref_fp2_add(lambda, lambda, E->a);
|
||||
oqs_sidh_iqc_ref_fp2_mul_scaler_si(temp, P->y, 2);
|
||||
oqs_sidh_iqc_ref_fp2_div(lambda, lambda, temp);
|
||||
|
||||
oqs_sidh_iqc_ref_point_add_with_lambda(R, P, P, lambda);
|
||||
|
||||
oqs_sidh_iqc_ref_fp2_clear(temp);
|
||||
oqs_sidh_iqc_ref_fp2_clear(lambda);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_point_add(point_t R,
|
||||
const point_t P,
|
||||
const point_t Q,
|
||||
const elliptic_curve_t E) {
|
||||
if (oqs_sidh_iqc_ref_point_is_zero(P)) {
|
||||
oqs_sidh_iqc_ref_point_set(R, Q);
|
||||
return;
|
||||
}
|
||||
|
||||
if (oqs_sidh_iqc_ref_point_is_zero(Q)) {
|
||||
oqs_sidh_iqc_ref_point_set(R, P);
|
||||
return;
|
||||
}
|
||||
|
||||
if (oqs_sidh_iqc_ref_fp2_equals(P->x, Q->x)) {
|
||||
if (oqs_sidh_iqc_ref_fp2_equals(P->y, Q->y)) {
|
||||
oqs_sidh_iqc_ref_point_double(R, P, E);
|
||||
return;
|
||||
}
|
||||
|
||||
oqs_sidh_iqc_ref_point_zero(R);
|
||||
return;
|
||||
}
|
||||
|
||||
fp2_element_t temp;
|
||||
fp2_element_t lambda;
|
||||
|
||||
oqs_sidh_iqc_ref_fp2_init(temp);
|
||||
oqs_sidh_iqc_ref_fp2_init(lambda);
|
||||
|
||||
// lambda = (y_Q - y_P) / (x_Q - x_P)
|
||||
oqs_sidh_iqc_ref_fp2_sub(lambda, Q->y, P->y);
|
||||
oqs_sidh_iqc_ref_fp2_sub(temp, Q->x, P->x);
|
||||
oqs_sidh_iqc_ref_fp2_div(lambda, lambda, temp);
|
||||
|
||||
oqs_sidh_iqc_ref_point_add_with_lambda(R, P, Q, lambda);
|
||||
|
||||
oqs_sidh_iqc_ref_fp2_clear(temp);
|
||||
oqs_sidh_iqc_ref_fp2_clear(lambda);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_point_sub(point_t R,
|
||||
const point_t P,
|
||||
const point_t Q,
|
||||
const elliptic_curve_t E) {
|
||||
point_t temp;
|
||||
oqs_sidh_iqc_ref_point_init(temp);
|
||||
oqs_sidh_iqc_ref_point_negate(temp, Q);
|
||||
oqs_sidh_iqc_ref_point_add(R, P, temp, E);
|
||||
oqs_sidh_iqc_ref_point_clear(temp);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_point_mul_scaler(point_t R,
|
||||
const point_t P,
|
||||
const mpz_t scaler,
|
||||
const elliptic_curve_t E) {
|
||||
if (mpz_cmp_ui(scaler, 0) == 0) {
|
||||
oqs_sidh_iqc_ref_point_zero(R);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mpz_cmp_ui(scaler, 1) == 0) {
|
||||
oqs_sidh_iqc_ref_point_set(R, P);
|
||||
return;
|
||||
}
|
||||
|
||||
point_t R0;
|
||||
point_t R1;
|
||||
|
||||
oqs_sidh_iqc_ref_point_init(R0);
|
||||
oqs_sidh_iqc_ref_point_init(R1);
|
||||
oqs_sidh_iqc_ref_point_set(R1, P);
|
||||
|
||||
long num_bits = mpz_sizeinbase(scaler, 2);
|
||||
for (long i = 0; i < num_bits; i++) {
|
||||
if (mpz_tstbit(scaler, i) == 1)
|
||||
oqs_sidh_iqc_ref_point_add(R0, R0, R1, E);
|
||||
oqs_sidh_iqc_ref_point_double(R1, R1, E);
|
||||
}
|
||||
|
||||
if (mpz_sgn(scaler) < 0)
|
||||
oqs_sidh_iqc_ref_point_negate(R0, R0);
|
||||
|
||||
oqs_sidh_iqc_ref_point_set(R, R0);
|
||||
oqs_sidh_iqc_ref_point_clear(R0);
|
||||
oqs_sidh_iqc_ref_point_clear(R1);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_point_mul_scaler_si(point_t R,
|
||||
const point_t P,
|
||||
long scaler,
|
||||
const elliptic_curve_t E) {
|
||||
mpz_t temp;
|
||||
mpz_init_set_si(temp, scaler);
|
||||
oqs_sidh_iqc_ref_point_mul_scaler(R, P, temp, E);
|
||||
mpz_clear(temp);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_elliptic_curve_compute_j_inv(fp2_element_t j_inv,
|
||||
const elliptic_curve_t E) {
|
||||
fp2_element_t result;
|
||||
fp2_element_t temp;
|
||||
oqs_sidh_iqc_ref_fp2_init(result);
|
||||
oqs_sidh_iqc_ref_fp2_init(temp);
|
||||
|
||||
oqs_sidh_iqc_ref_fp2_pow_ui(temp, E->a, 3);
|
||||
oqs_sidh_iqc_ref_fp2_mul_scaler_si(temp, temp, 4);
|
||||
oqs_sidh_iqc_ref_fp2_square(result, E->b);
|
||||
oqs_sidh_iqc_ref_fp2_mul_scaler_si(result, result, 27);
|
||||
oqs_sidh_iqc_ref_fp2_add(result, result, temp);
|
||||
oqs_sidh_iqc_ref_fp2_inv(result, result);
|
||||
oqs_sidh_iqc_ref_fp2_mul(result, result, temp);
|
||||
oqs_sidh_iqc_ref_fp2_mul_scaler_si(result, result, 1728);
|
||||
oqs_sidh_iqc_ref_fp2_set(j_inv, result);
|
||||
|
||||
oqs_sidh_iqc_ref_fp2_clear(result);
|
||||
oqs_sidh_iqc_ref_fp2_clear(temp);
|
||||
}
|
||||
|
||||
int oqs_sidh_iqc_ref_point_is_on_curve(const point_t P,
|
||||
const elliptic_curve_t E) {
|
||||
|
||||
if (oqs_sidh_iqc_ref_point_is_zero(P))
|
||||
return 1;
|
||||
|
||||
fp2_element_t temp_x;
|
||||
oqs_sidh_iqc_ref_fp2_init(temp_x);
|
||||
|
||||
// compute x^3 + a * x + b = x * (x^2 + a) + b
|
||||
oqs_sidh_iqc_ref_fp2_square(temp_x, P->x);
|
||||
oqs_sidh_iqc_ref_fp2_add(temp_x, temp_x, E->a);
|
||||
oqs_sidh_iqc_ref_fp2_mul(temp_x, temp_x, P->x);
|
||||
oqs_sidh_iqc_ref_fp2_add(temp_x, temp_x, E->b);
|
||||
|
||||
fp2_element_t temp_y;
|
||||
oqs_sidh_iqc_ref_fp2_init(temp_y);
|
||||
oqs_sidh_iqc_ref_fp2_square(temp_y, P->y);
|
||||
|
||||
int result = oqs_sidh_iqc_ref_fp2_equals(temp_y, temp_x);
|
||||
|
||||
oqs_sidh_iqc_ref_fp2_clear(temp_x);
|
||||
oqs_sidh_iqc_ref_fp2_clear(temp_y);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_elliptic_curve_random_point(point_t P,
|
||||
const elliptic_curve_t E) {
|
||||
point_t result;
|
||||
oqs_sidh_iqc_ref_point_init(result);
|
||||
result->z = 1;
|
||||
|
||||
fp2_element_t temp_x;
|
||||
oqs_sidh_iqc_ref_fp2_init(temp_x);
|
||||
|
||||
fp2_element_t temp_y;
|
||||
oqs_sidh_iqc_ref_fp2_init(temp_y);
|
||||
|
||||
gmp_randstate_t randstate;
|
||||
gmp_randinit_default(randstate);
|
||||
|
||||
while (1) {
|
||||
oqs_sidh_iqc_ref_fp2_random(result->x, randstate);
|
||||
|
||||
// compute x^3 + a * x + b = x * (x^2 + a) + b
|
||||
oqs_sidh_iqc_ref_fp2_square(temp_x, result->x);
|
||||
oqs_sidh_iqc_ref_fp2_add(temp_x, temp_x, E->a);
|
||||
oqs_sidh_iqc_ref_fp2_mul(temp_x, temp_x, result->x);
|
||||
oqs_sidh_iqc_ref_fp2_add(temp_x, temp_x, E->b);
|
||||
|
||||
if (oqs_sidh_iqc_ref_fp2_is_square(temp_x)) {
|
||||
oqs_sidh_iqc_ref_fp2_sqrt(result->y, temp_x);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
oqs_sidh_iqc_ref_point_set(P, result);
|
||||
|
||||
oqs_sidh_iqc_ref_point_clear(result);
|
||||
oqs_sidh_iqc_ref_fp2_clear(temp_x);
|
||||
oqs_sidh_iqc_ref_fp2_clear(temp_y);
|
||||
gmp_randclear(randstate);
|
||||
}
|
259
src/kex_sidh_iqc_ref/sidh_elliptic_curve.h
Normal file
259
src/kex_sidh_iqc_ref/sidh_elliptic_curve.h
Normal file
@ -0,0 +1,259 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CURVE_H
|
||||
#define CURVE_H
|
||||
|
||||
#include "sidh_quadratic_ext.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Representation of the elliptic curve y^2 = x^3 + a * x^2 + b * x
|
||||
*/
|
||||
typedef struct {
|
||||
fp2_element_t a;
|
||||
fp2_element_t b;
|
||||
} elliptic_curve_struct;
|
||||
|
||||
typedef elliptic_curve_struct elliptic_curve_t[1];
|
||||
|
||||
/**
|
||||
* Representation of a point in the standard affine D+(z) of the
|
||||
* plain projective projective space
|
||||
*/
|
||||
typedef struct {
|
||||
fp2_element_t x;
|
||||
fp2_element_t y;
|
||||
int z;
|
||||
} point_struct;
|
||||
|
||||
typedef point_struct point_t[1];
|
||||
|
||||
/**
|
||||
* Initializes the input curve to y^2 = x^3 + x + 1.
|
||||
* @param E
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_elliptic_curve_init(elliptic_curve_t E);
|
||||
|
||||
/**
|
||||
* Copies T into E
|
||||
* @param E
|
||||
* @param T
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_elliptic_curve_set(elliptic_curve_t E,
|
||||
const elliptic_curve_t T);
|
||||
|
||||
/**
|
||||
* Sets the coefficients of E: y^2 = x^3 + a * x^2 + b * x.
|
||||
* @param E
|
||||
* @param a
|
||||
* @param b
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_elliptic_curve_set_coeffs(elliptic_curve_t E,
|
||||
const fp2_element_t a,
|
||||
const fp2_element_t b);
|
||||
|
||||
/**
|
||||
* Initializes the point {@code P} to the zero point (0 : 1 : 0).
|
||||
* @param P
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_point_init(point_t P);
|
||||
|
||||
/**
|
||||
* Sets the coordinates of the point {@code P}.
|
||||
* @param P
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_point_set_coordinates(point_t P,
|
||||
const fp2_element_t x,
|
||||
const fp2_element_t y,
|
||||
int z);
|
||||
|
||||
/**
|
||||
* Copies {@code Q} into {@code P}
|
||||
* @param P
|
||||
* @param Q
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_point_set(point_t P,
|
||||
const point_t Q);
|
||||
|
||||
/**
|
||||
* Sets the given point to zero.
|
||||
* @param P
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_point_zero(point_t P);
|
||||
|
||||
/**
|
||||
* Checks if a given point is zero.
|
||||
* @param P
|
||||
* @return
|
||||
*/
|
||||
int oqs_sidh_iqc_ref_point_is_zero(const point_t P);
|
||||
|
||||
/**
|
||||
* Sets {@code P} to {@code -Q} as a group element.
|
||||
* @param P
|
||||
* @param Q
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_point_negate(point_t P,
|
||||
const point_t Q);
|
||||
|
||||
/**
|
||||
* Checks if 2 * {@code P} = 0.
|
||||
* @param P
|
||||
* @return
|
||||
*/
|
||||
int oqs_sidh_iqc_ref_point_has_order_2(const point_t P);
|
||||
|
||||
/**
|
||||
* Frees the memory allocated to {@code E}.
|
||||
* @param E
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_elliptic_curve_clear(elliptic_curve_t E);
|
||||
|
||||
/**
|
||||
* Frees the memory allocated to {@code P}.
|
||||
* @param P
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_point_clear(point_t P);
|
||||
|
||||
/**
|
||||
* Checks if {@code P = Q}.
|
||||
* @param P
|
||||
* @param Q
|
||||
* @return 1 if the points are equal, 0 otherwise
|
||||
*/
|
||||
int oqs_sidh_iqc_ref_point_equals(const point_t P,
|
||||
const point_t Q);
|
||||
|
||||
/**
|
||||
* @param E
|
||||
* @return A string representation of {@code E}
|
||||
*/
|
||||
char *oqs_sidh_iqc_ref_elliptic_curve_get_str(const elliptic_curve_t E);
|
||||
|
||||
/**
|
||||
* @param P
|
||||
* @return A string representation of {@code P}
|
||||
*/
|
||||
char *oqs_sidh_iqc_ref_point_get_str(const point_t P);
|
||||
|
||||
/**
|
||||
* Sets {@code R = P + Q} on {@code E}.
|
||||
* @param R
|
||||
* @param P
|
||||
* @param Q
|
||||
* @param E
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_point_add(point_t R,
|
||||
const point_t P,
|
||||
const point_t Q,
|
||||
const elliptic_curve_t E);
|
||||
|
||||
/**
|
||||
* Sets {@code R = P - Q}.
|
||||
* @param R
|
||||
* @param P
|
||||
* @param Q
|
||||
* @param E
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_point_sub(point_t R,
|
||||
const point_t P,
|
||||
const point_t Q,
|
||||
const elliptic_curve_t E);
|
||||
|
||||
/**
|
||||
* Sets {@code R = P + Q} on {@code E}.
|
||||
* @param R
|
||||
* @param P
|
||||
* @param Q
|
||||
* @param lambda The slope of the line passing through {@code P, Q}
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_point_add_with_lambda(point_t R,
|
||||
const point_t P,
|
||||
const point_t Q,
|
||||
const fp2_element_t lambda);
|
||||
|
||||
/**
|
||||
* Sets {@code R = 2 * P} on {@code E}.
|
||||
* @param R
|
||||
* @param P
|
||||
* @param E
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_point_double(point_t R,
|
||||
const point_t P,
|
||||
const elliptic_curve_t E);
|
||||
|
||||
/**
|
||||
* Sets {@code R = scaler * P} on {@code E}.
|
||||
* @param R
|
||||
* @param P
|
||||
* @param scaler
|
||||
* @param E
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_point_mul_scaler(point_t R,
|
||||
const point_t P,
|
||||
const mpz_t scaler,
|
||||
const elliptic_curve_t E);
|
||||
|
||||
/**
|
||||
* {@link oqs_sidh_iqc_ref_point_mul_scaler}
|
||||
* @param R
|
||||
* @param P
|
||||
* @param scaler
|
||||
* @param E
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_point_mul_scaler_si(point_t R,
|
||||
const point_t P,
|
||||
long scaler,
|
||||
const elliptic_curve_t E);
|
||||
|
||||
/**
|
||||
* Computes the j-invariant of {@code E}.
|
||||
* @param j_inv
|
||||
* @param E
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_elliptic_curve_compute_j_inv(fp2_element_t j_inv,
|
||||
const elliptic_curve_t E);
|
||||
|
||||
/**
|
||||
* Checks if the point {@code P} is on the curve {@code E}.
|
||||
* @param P
|
||||
* @param E
|
||||
* @return 1 if the point is on the curve, 0 otherwise
|
||||
*/
|
||||
int oqs_sidh_iqc_ref_point_is_on_curve(const point_t P,
|
||||
const elliptic_curve_t E);
|
||||
|
||||
/**
|
||||
* Generates a random point on the curve {@code E}.
|
||||
* @param P the generated random point.
|
||||
* @param E
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_elliptic_curve_random_point(point_t P,
|
||||
const elliptic_curve_t E);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CURVE_H */
|
114
src/kex_sidh_iqc_ref/sidh_elliptic_curve_dlp.c
Normal file
114
src/kex_sidh_iqc_ref/sidh_elliptic_curve_dlp.c
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "sidh_elliptic_curve_dlp.h"
|
||||
#include <stdio.h>
|
||||
|
||||
void oqs_sidh_iqc_ref_elliptic_curve_prime_power_dlp(mpz_t x,
|
||||
const point_t P,
|
||||
const point_t Q,
|
||||
const elliptic_curve_t E,
|
||||
long l,
|
||||
long e) {
|
||||
mpz_t exponent1;
|
||||
mpz_t exponent2;
|
||||
point_t temp_P;
|
||||
point_t temp_Q;
|
||||
point_t temp_R;
|
||||
point_t PP;
|
||||
|
||||
mpz_init(exponent1);
|
||||
mpz_init(exponent2);
|
||||
oqs_sidh_iqc_ref_point_init(temp_P);
|
||||
oqs_sidh_iqc_ref_point_init(temp_Q);
|
||||
oqs_sidh_iqc_ref_point_init(temp_R);
|
||||
oqs_sidh_iqc_ref_point_init(PP);
|
||||
|
||||
int ladic_rep[e];
|
||||
mpz_ui_pow_ui(exponent1, l, e - 1);
|
||||
|
||||
// PP = l^(e - 1) * P once and for all
|
||||
oqs_sidh_iqc_ref_point_mul_scaler(PP, P, exponent1, E);
|
||||
|
||||
// compute the first ladic coefficient
|
||||
oqs_sidh_iqc_ref_point_mul_scaler(temp_Q, Q, exponent1, E);
|
||||
long ladic_coeff = oqs_sidh_iqc_ref_elliptic_curve_prime_dlp(PP, temp_Q, E, l);
|
||||
|
||||
for (int j = 1; j < e; j++) {
|
||||
if (ladic_coeff >= 0) {
|
||||
ladic_rep[j - 1] = ladic_coeff;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
mpz_ui_pow_ui(exponent2, l, j - 1);
|
||||
mpz_mul_ui(exponent2, exponent2, ladic_rep[j - 1]);
|
||||
mpz_divexact_ui(exponent1, exponent1, l);
|
||||
oqs_sidh_iqc_ref_point_mul_scaler(temp_P, P, exponent2, E);
|
||||
oqs_sidh_iqc_ref_point_add(temp_R, temp_R, temp_P, E);
|
||||
oqs_sidh_iqc_ref_point_sub(temp_Q, Q, temp_R, E);
|
||||
oqs_sidh_iqc_ref_point_mul_scaler(temp_Q, temp_Q, exponent1, E);
|
||||
ladic_coeff = oqs_sidh_iqc_ref_elliptic_curve_prime_dlp(PP, temp_Q, E, l);
|
||||
}
|
||||
|
||||
if (ladic_coeff >= 0) {
|
||||
ladic_rep[e - 1] = ladic_coeff;
|
||||
|
||||
// set x = l_{e - 1}l^{e - 1} + ... + l_1l + l_0
|
||||
mpz_set_ui(x, ladic_rep[e - 1]);
|
||||
for (long i = e - 2; i >= 0; i--) {
|
||||
mpz_mul_ui(x, x, l);
|
||||
mpz_add_ui(x, x, ladic_rep[i]);
|
||||
}
|
||||
} else {
|
||||
mpz_set_si(x, -1);
|
||||
}
|
||||
|
||||
mpz_clear(exponent1);
|
||||
mpz_clear(exponent2);
|
||||
oqs_sidh_iqc_ref_point_clear(temp_P);
|
||||
oqs_sidh_iqc_ref_point_clear(temp_Q);
|
||||
oqs_sidh_iqc_ref_point_clear(temp_R);
|
||||
oqs_sidh_iqc_ref_point_clear(PP);
|
||||
}
|
||||
|
||||
long oqs_sidh_iqc_ref_elliptic_curve_prime_dlp(const point_t P,
|
||||
const point_t Q,
|
||||
const elliptic_curve_t E,
|
||||
long l) {
|
||||
if (oqs_sidh_iqc_ref_point_is_zero(Q))
|
||||
return 0;
|
||||
|
||||
if (oqs_sidh_iqc_ref_point_equals(P, Q))
|
||||
return 1;
|
||||
|
||||
point_t temp;
|
||||
oqs_sidh_iqc_ref_point_init(temp);
|
||||
oqs_sidh_iqc_ref_point_set(temp, P);
|
||||
|
||||
long result = -1;
|
||||
for (long i = 2; i < l; i++) {
|
||||
oqs_sidh_iqc_ref_point_add(temp, temp, P, E);
|
||||
if (oqs_sidh_iqc_ref_point_equals(temp, Q)) {
|
||||
result = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
oqs_sidh_iqc_ref_point_clear(temp);
|
||||
return result;
|
||||
}
|
62
src/kex_sidh_iqc_ref/sidh_elliptic_curve_dlp.h
Normal file
62
src/kex_sidh_iqc_ref/sidh_elliptic_curve_dlp.h
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ELLIPTIC_CURVE_DLP_H
|
||||
#define ELLIPTIC_CURVE_DLP_H
|
||||
|
||||
#include "sidh_elliptic_curve.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Computes the discrete logarithm {@code P = x * Q} in a group of order
|
||||
* {@code l^e} generated by {@code P}. The Pohlig–Hellman algorithm is used.
|
||||
* @param x the discrete logarithm if it exists, or -1 otherwise
|
||||
* @param P the generator of the cyclic group
|
||||
* @param Q an element in the the group generated by {@code P}
|
||||
* @param E
|
||||
* @param l a prime number
|
||||
* @param e a positive integer
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_elliptic_curve_prime_power_dlp(mpz_t x,
|
||||
const point_t P,
|
||||
const point_t Q,
|
||||
const elliptic_curve_t E,
|
||||
long l,
|
||||
long e);
|
||||
|
||||
/**
|
||||
* Computes the discrete logarithm {@code P = x * Q} in a group of order
|
||||
* {@code l} generated by {@code P}.
|
||||
* @param P the generator of the cyclic group
|
||||
* @param Q an element in the the group generated by {@code P}
|
||||
* @param E
|
||||
* @param l a prime number
|
||||
* @return the discrete logarithm if it exists, or -1 otherwise
|
||||
*/
|
||||
long oqs_sidh_iqc_ref_elliptic_curve_prime_dlp(const point_t P,
|
||||
const point_t Q,
|
||||
const elliptic_curve_t E,
|
||||
long l);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ELLIPTIC_CURVE_DLP_H */
|
487
src/kex_sidh_iqc_ref/sidh_isogeny.c
Normal file
487
src/kex_sidh_iqc_ref/sidh_isogeny.c
Normal file
@ -0,0 +1,487 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "sidh_isogeny.h"
|
||||
#include <math.h>
|
||||
|
||||
void oqs_sidh_iqc_ref_isogeny_init(isogeny_t isogeny,
|
||||
long kernel_size) {
|
||||
isogeny->kernel_size = 0;
|
||||
isogeny->partition_size = 0;
|
||||
oqs_sidh_iqc_ref_isogeny_set_kernel_size(isogeny, kernel_size);
|
||||
long size = isogeny->partition_size;
|
||||
isogeny->partition = (point_t *) malloc(size * sizeof(point_t));
|
||||
isogeny->gx = (fp2_element_t *) malloc(size * sizeof(fp2_element_t));
|
||||
isogeny->gy = (fp2_element_t *) malloc(size * sizeof(fp2_element_t));
|
||||
isogeny->u = (fp2_element_t *) malloc(size * sizeof(fp2_element_t));
|
||||
isogeny->v = (fp2_element_t *) malloc(size * sizeof(fp2_element_t));
|
||||
|
||||
oqs_sidh_iqc_ref_elliptic_curve_init(isogeny->domain);
|
||||
oqs_sidh_iqc_ref_elliptic_curve_init(isogeny->codomain);
|
||||
|
||||
for (long i = 0; i < size; i++) {
|
||||
oqs_sidh_iqc_ref_point_init(isogeny->partition[i]);
|
||||
oqs_sidh_iqc_ref_fp2_init(isogeny->gx[i]);
|
||||
oqs_sidh_iqc_ref_fp2_init(isogeny->gy[i]);
|
||||
oqs_sidh_iqc_ref_fp2_init(isogeny->u[i]);
|
||||
oqs_sidh_iqc_ref_fp2_init(isogeny->v[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_isogeny_clear(isogeny_t isogeny) {
|
||||
oqs_sidh_iqc_ref_elliptic_curve_clear(isogeny->domain);
|
||||
oqs_sidh_iqc_ref_elliptic_curve_clear(isogeny->codomain);
|
||||
|
||||
for (long i = 0; i < isogeny->partition_size; i++) {
|
||||
oqs_sidh_iqc_ref_point_clear(isogeny->partition[i]);
|
||||
oqs_sidh_iqc_ref_fp2_clear(isogeny->gx[i]);
|
||||
oqs_sidh_iqc_ref_fp2_clear(isogeny->gy[i]);
|
||||
oqs_sidh_iqc_ref_fp2_clear(isogeny->u[i]);
|
||||
oqs_sidh_iqc_ref_fp2_clear(isogeny->v[i]);
|
||||
}
|
||||
|
||||
free(isogeny->partition);
|
||||
free(isogeny->gx);
|
||||
free(isogeny->gy);
|
||||
free(isogeny->u);
|
||||
free(isogeny->v);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_isogeny_compute(isogeny_t isogeny,
|
||||
const point_t kernel_gen) {
|
||||
oqs_sidh_iqc_ref_isogeny_partition_kernel(isogeny->partition,
|
||||
isogeny->partition_size,
|
||||
kernel_gen,
|
||||
isogeny->domain);
|
||||
long size = isogeny->partition_size;
|
||||
|
||||
// compute gx_P = 3 * x_P^2 + a
|
||||
for (long i = 0; i < size; i++) {
|
||||
oqs_sidh_iqc_ref_fp2_square(isogeny->gx[i], isogeny->partition[i]->x);
|
||||
oqs_sidh_iqc_ref_fp2_mul_scaler_si(isogeny->gx[i], isogeny->gx[i], 3);
|
||||
oqs_sidh_iqc_ref_fp2_add(isogeny->gx[i], isogeny->gx[i], isogeny->domain->a);
|
||||
}
|
||||
|
||||
// compute gy_P = -2y_P
|
||||
for (long i = 0; i < size; i++) {
|
||||
oqs_sidh_iqc_ref_fp2_mul_scaler_si(isogeny->gy[i], isogeny->partition[i]->y, -2);
|
||||
}
|
||||
|
||||
// compute v_P = gx_P or 2gx_P
|
||||
for (long i = 0; i < size; i++) {
|
||||
if (oqs_sidh_iqc_ref_point_has_order_2(isogeny->partition[i]))
|
||||
oqs_sidh_iqc_ref_fp2_set(isogeny->v[i], isogeny->gx[i]);
|
||||
else
|
||||
oqs_sidh_iqc_ref_fp2_mul_scaler_si(isogeny->v[i], isogeny->gx[i], 2);
|
||||
}
|
||||
|
||||
// compute u_P = gy_P^2
|
||||
for (long i = 0; i < size; i++) {
|
||||
oqs_sidh_iqc_ref_fp2_square(isogeny->u[i], isogeny->gy[i]);
|
||||
}
|
||||
|
||||
// compute the codomain curve
|
||||
fp2_element_t v;
|
||||
fp2_element_t w;
|
||||
fp2_element_t temp;
|
||||
oqs_sidh_iqc_ref_fp2_init(v);
|
||||
oqs_sidh_iqc_ref_fp2_init(w);
|
||||
oqs_sidh_iqc_ref_fp2_init(temp);
|
||||
|
||||
for (long i = 0; i < size; i++) {
|
||||
oqs_sidh_iqc_ref_fp2_add(v, v, isogeny->v[i]);
|
||||
oqs_sidh_iqc_ref_fp2_mul(temp, isogeny->v[i], isogeny->partition[i]->x);
|
||||
oqs_sidh_iqc_ref_fp2_add(temp, isogeny->u[i], temp);
|
||||
oqs_sidh_iqc_ref_fp2_add(w, w, temp);
|
||||
}
|
||||
|
||||
oqs_sidh_iqc_ref_fp2_mul_scaler_si(v, v, 5);
|
||||
oqs_sidh_iqc_ref_fp2_sub(v, isogeny->domain->a, v);
|
||||
oqs_sidh_iqc_ref_fp2_mul_scaler_si(w, w, 7);
|
||||
oqs_sidh_iqc_ref_fp2_sub(w, isogeny->domain->b, w);
|
||||
oqs_sidh_iqc_ref_elliptic_curve_set_coeffs(isogeny->codomain, v, w);
|
||||
|
||||
oqs_sidh_iqc_ref_fp2_clear(v);
|
||||
oqs_sidh_iqc_ref_fp2_clear(w);
|
||||
oqs_sidh_iqc_ref_fp2_clear(temp);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_isogeny_partition_kernel(point_t *partition,
|
||||
long partition_size,
|
||||
const point_t kernel_gen,
|
||||
const elliptic_curve_t E) {
|
||||
oqs_sidh_iqc_ref_point_set(partition[0], kernel_gen);
|
||||
for (long i = 1; i < partition_size; i++) {
|
||||
oqs_sidh_iqc_ref_point_add(partition[i], partition[i - 1], kernel_gen, E);
|
||||
}
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_isogeny_set_kernel_size(isogeny_t isogeny,
|
||||
long kernel_size) {
|
||||
long current_size = isogeny->kernel_size;
|
||||
if (current_size != 0 && current_size <= kernel_size)
|
||||
return;
|
||||
|
||||
current_size = isogeny->partition_size;
|
||||
isogeny->kernel_size = kernel_size;
|
||||
|
||||
if (kernel_size % 2 == 0)
|
||||
isogeny->partition_size = kernel_size / 2;
|
||||
else
|
||||
isogeny->partition_size = (kernel_size - 1) / 2;
|
||||
|
||||
// clear the the unused memory after shrinking
|
||||
for (long i = isogeny->partition_size; i < current_size; i++) {
|
||||
oqs_sidh_iqc_ref_point_clear(isogeny->partition[i]);
|
||||
oqs_sidh_iqc_ref_fp2_clear(isogeny->gx[i]);
|
||||
oqs_sidh_iqc_ref_fp2_clear(isogeny->gy[i]);
|
||||
oqs_sidh_iqc_ref_fp2_clear(isogeny->u[i]);
|
||||
oqs_sidh_iqc_ref_fp2_clear(isogeny->v[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_isogeny_evaluate_velu(point_t Q,
|
||||
const isogeny_t isogeny,
|
||||
const point_t P) {
|
||||
|
||||
if (oqs_sidh_iqc_ref_point_is_zero(P)) {
|
||||
oqs_sidh_iqc_ref_point_zero(Q);
|
||||
return;
|
||||
}
|
||||
|
||||
long size = isogeny->partition_size;
|
||||
|
||||
fp2_element_t temp1;
|
||||
fp2_element_t temp2;
|
||||
fp2_element_t temp3;
|
||||
oqs_sidh_iqc_ref_fp2_init(temp1);
|
||||
oqs_sidh_iqc_ref_fp2_init(temp2);
|
||||
oqs_sidh_iqc_ref_fp2_init(temp3);
|
||||
|
||||
point_t result;
|
||||
oqs_sidh_iqc_ref_point_init(result);
|
||||
oqs_sidh_iqc_ref_point_set(result, P);
|
||||
|
||||
for (long i = 0; i < size; i++) {
|
||||
oqs_sidh_iqc_ref_fp2_sub(temp1, P->x, isogeny->partition[i]->x);
|
||||
|
||||
// check if the point is in the kernel
|
||||
if (oqs_sidh_iqc_ref_fp2_is_zero(temp1)) {
|
||||
oqs_sidh_iqc_ref_point_zero(result);
|
||||
break;
|
||||
}
|
||||
|
||||
// 1 / (x - x_P)
|
||||
oqs_sidh_iqc_ref_fp2_inv(temp1, temp1);
|
||||
|
||||
// add 1 / (x - x_P) * (v_P + u_P / (x - x_P)) to x
|
||||
oqs_sidh_iqc_ref_fp2_mul(temp2, isogeny->u[i], temp1);
|
||||
oqs_sidh_iqc_ref_fp2_add(temp2, temp2, isogeny->v[i]);
|
||||
oqs_sidh_iqc_ref_fp2_mul(temp2, temp2, temp1);
|
||||
oqs_sidh_iqc_ref_fp2_add(result->x, result->x, temp2);
|
||||
|
||||
// v_P * (y - y_P) - gx_P * gy_P
|
||||
oqs_sidh_iqc_ref_fp2_sub(temp2, P->y, isogeny->partition[i]->y);
|
||||
oqs_sidh_iqc_ref_fp2_mul(temp2, temp2, isogeny->v[i]);
|
||||
oqs_sidh_iqc_ref_fp2_mul(temp3, isogeny->gx[i], isogeny->gy[i]);
|
||||
oqs_sidh_iqc_ref_fp2_sub(temp2, temp2, temp3);
|
||||
|
||||
// 2 * u_P * y / (x - x_P)
|
||||
oqs_sidh_iqc_ref_fp2_mul(temp3, isogeny->u[i], P->y);
|
||||
oqs_sidh_iqc_ref_fp2_mul_scaler_si(temp3, temp3, 2);
|
||||
oqs_sidh_iqc_ref_fp2_mul(temp3, temp3, temp1);
|
||||
|
||||
oqs_sidh_iqc_ref_fp2_add(temp3, temp3, temp2);
|
||||
oqs_sidh_iqc_ref_fp2_square(temp1, temp1);
|
||||
oqs_sidh_iqc_ref_fp2_mul(temp3, temp3, temp1);
|
||||
oqs_sidh_iqc_ref_fp2_sub(result->y, result->y, temp3);
|
||||
}
|
||||
|
||||
oqs_sidh_iqc_ref_point_set(Q, result);
|
||||
|
||||
oqs_sidh_iqc_ref_point_clear(result);
|
||||
oqs_sidh_iqc_ref_fp2_clear(temp1);
|
||||
oqs_sidh_iqc_ref_fp2_clear(temp2);
|
||||
oqs_sidh_iqc_ref_fp2_clear(temp3);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_isogeny_evaluate_kohel(point_t Q,
|
||||
const isogeny_t isogeny,
|
||||
const point_t P) {
|
||||
fp2_element_t ix1;
|
||||
fp2_element_t ix2;
|
||||
fp2_element_t ix3;
|
||||
fp2_element_t temp1;
|
||||
fp2_element_t temp2;
|
||||
fp2_element_t temp3;
|
||||
fp2_element_t sigma1;
|
||||
|
||||
oqs_sidh_iqc_ref_fp2_init(ix1);
|
||||
oqs_sidh_iqc_ref_fp2_init(ix2);
|
||||
oqs_sidh_iqc_ref_fp2_init(ix3);
|
||||
oqs_sidh_iqc_ref_fp2_init(temp1);
|
||||
oqs_sidh_iqc_ref_fp2_init(temp2);
|
||||
oqs_sidh_iqc_ref_fp2_init(temp3);
|
||||
oqs_sidh_iqc_ref_fp2_init(sigma1);
|
||||
|
||||
point_t result;
|
||||
oqs_sidh_iqc_ref_point_init(result);
|
||||
oqs_sidh_iqc_ref_point_set(result, P);
|
||||
|
||||
long size = isogeny->partition_size;
|
||||
|
||||
for (long i = 0; i < size; i++) {
|
||||
oqs_sidh_iqc_ref_fp2_add(sigma1, sigma1, isogeny->partition[i]->x);
|
||||
oqs_sidh_iqc_ref_fp2_sub(temp1, P->x, isogeny->partition[i]->x);
|
||||
|
||||
// check if the point is in the kernel
|
||||
if (oqs_sidh_iqc_ref_fp2_is_zero(temp1)) {
|
||||
oqs_sidh_iqc_ref_point_zero(result);
|
||||
break;
|
||||
}
|
||||
|
||||
// 1 / (x - x_P)
|
||||
oqs_sidh_iqc_ref_fp2_inv(temp1, temp1);
|
||||
|
||||
// 1 / (x - x_P)^2
|
||||
oqs_sidh_iqc_ref_fp2_square(temp2, temp1);
|
||||
|
||||
// 1 / (x - x_P)^3
|
||||
oqs_sidh_iqc_ref_fp2_mul(temp3, temp2, temp1);
|
||||
|
||||
if (!oqs_sidh_iqc_ref_point_has_order_2(isogeny->partition[i])) {
|
||||
oqs_sidh_iqc_ref_fp2_add(temp1, temp1, temp1);
|
||||
oqs_sidh_iqc_ref_fp2_add(temp2, temp2, temp2);
|
||||
oqs_sidh_iqc_ref_fp2_add(temp3, temp3, temp3);
|
||||
oqs_sidh_iqc_ref_fp2_add(sigma1, sigma1, isogeny->partition[i]->x);
|
||||
}
|
||||
|
||||
oqs_sidh_iqc_ref_fp2_add(ix1, ix1, temp1);
|
||||
oqs_sidh_iqc_ref_fp2_add(ix2, ix2, temp2);
|
||||
oqs_sidh_iqc_ref_fp2_add(ix3, ix3, temp3);
|
||||
}
|
||||
|
||||
if (!oqs_sidh_iqc_ref_point_is_zero(result)) {
|
||||
fp2_element_t u1;
|
||||
fp2_element_t u2;
|
||||
|
||||
oqs_sidh_iqc_ref_fp2_init(u1);
|
||||
oqs_sidh_iqc_ref_fp2_init(u2);
|
||||
|
||||
// 3 * x^2 + a
|
||||
oqs_sidh_iqc_ref_fp2_square(u1, P->x);
|
||||
oqs_sidh_iqc_ref_fp2_mul_scaler_si(u1, u1, 3);
|
||||
oqs_sidh_iqc_ref_fp2_add(u1, u1, isogeny->domain->a);
|
||||
|
||||
// 2 * y^2
|
||||
oqs_sidh_iqc_ref_fp2_square(u2, P->y);
|
||||
oqs_sidh_iqc_ref_fp2_mul_scaler_si(u2, u2, 2);
|
||||
|
||||
// compute the first coordinate
|
||||
oqs_sidh_iqc_ref_fp2_mul_scaler_si(result->x, P->x, isogeny->kernel_size);
|
||||
oqs_sidh_iqc_ref_fp2_sub(result->x, result->x, sigma1);
|
||||
oqs_sidh_iqc_ref_fp2_mul(temp1, u1, ix1);
|
||||
oqs_sidh_iqc_ref_fp2_sub(result->x, result->x, temp1);
|
||||
oqs_sidh_iqc_ref_fp2_mul(temp1, u2, ix2);
|
||||
oqs_sidh_iqc_ref_fp2_add(result->x, result->x, temp1);
|
||||
|
||||
// compute the second coordinate
|
||||
oqs_sidh_iqc_ref_fp2_mul_scaler_si(temp1, P->x, -6);
|
||||
oqs_sidh_iqc_ref_fp2_mul(result->y, temp1, ix1);
|
||||
oqs_sidh_iqc_ref_fp2_add_ui(result->y, result->y, isogeny->kernel_size);
|
||||
oqs_sidh_iqc_ref_fp2_mul_scaler_si(temp1, u1, 3);
|
||||
oqs_sidh_iqc_ref_fp2_mul(temp1, temp1, ix2);
|
||||
oqs_sidh_iqc_ref_fp2_add(result->y, result->y, temp1);
|
||||
oqs_sidh_iqc_ref_fp2_mul_scaler_si(temp1, u2, -2);
|
||||
oqs_sidh_iqc_ref_fp2_mul(temp1, temp1, ix3);
|
||||
oqs_sidh_iqc_ref_fp2_add(result->y, result->y, temp1);
|
||||
oqs_sidh_iqc_ref_fp2_mul(result->y, result->y, P->y);
|
||||
|
||||
oqs_sidh_iqc_ref_fp2_clear(u1);
|
||||
oqs_sidh_iqc_ref_fp2_clear(u2);
|
||||
}
|
||||
|
||||
oqs_sidh_iqc_ref_point_set(Q, result);
|
||||
|
||||
oqs_sidh_iqc_ref_point_clear(result);
|
||||
oqs_sidh_iqc_ref_fp2_clear(ix1);
|
||||
oqs_sidh_iqc_ref_fp2_clear(ix2);
|
||||
oqs_sidh_iqc_ref_fp2_clear(ix3);
|
||||
oqs_sidh_iqc_ref_fp2_clear(temp1);
|
||||
oqs_sidh_iqc_ref_fp2_clear(temp2);
|
||||
oqs_sidh_iqc_ref_fp2_clear(temp3);
|
||||
oqs_sidh_iqc_ref_fp2_clear(sigma1);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_isogeny_evaluate_naive(elliptic_curve_t E,
|
||||
point_t *points,
|
||||
long num_points,
|
||||
const point_t kernel_gen,
|
||||
long l,
|
||||
long e,
|
||||
long isogeny_jump) {
|
||||
|
||||
point_t temp_gen;
|
||||
oqs_sidh_iqc_ref_point_init(temp_gen);
|
||||
oqs_sidh_iqc_ref_point_set(temp_gen, kernel_gen);
|
||||
|
||||
mpz_t le;
|
||||
mpz_init(le);
|
||||
mpz_ui_pow_ui(le, l, e);
|
||||
|
||||
long kernel_size = 0;
|
||||
if (e <= isogeny_jump)
|
||||
kernel_size = mpz_get_si(le);
|
||||
else
|
||||
kernel_size = (long) pow(l, isogeny_jump);
|
||||
|
||||
isogeny_t isogeny;
|
||||
oqs_sidh_iqc_ref_isogeny_init(isogeny, kernel_size);
|
||||
oqs_sidh_iqc_ref_elliptic_curve_set(isogeny->domain, E);
|
||||
|
||||
long i = 0;
|
||||
while (i < e) {
|
||||
mpz_divexact_ui(le, le, kernel_size);
|
||||
oqs_sidh_iqc_ref_isogeny_evaluate_naive_helper(isogeny,
|
||||
E,
|
||||
points,
|
||||
num_points,
|
||||
temp_gen,
|
||||
le);
|
||||
i += isogeny_jump;
|
||||
|
||||
if ((e - i > 0) && (e - i) < isogeny_jump) {
|
||||
kernel_size = (long) pow(l, e - i);
|
||||
oqs_sidh_iqc_ref_isogeny_set_kernel_size(isogeny, kernel_size);
|
||||
}
|
||||
}
|
||||
|
||||
oqs_sidh_iqc_ref_point_clear(temp_gen);
|
||||
mpz_clear(le);
|
||||
oqs_sidh_iqc_ref_isogeny_clear(isogeny);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_isogeny_evaluate_naive_curve(elliptic_curve_t E,
|
||||
const point_t kernel_gen,
|
||||
long l,
|
||||
long e,
|
||||
long isogeny_jump) {
|
||||
oqs_sidh_iqc_ref_isogeny_evaluate_naive(E, NULL, 0, kernel_gen, l, e, isogeny_jump);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_isogeny_evaluate_naive_helper(isogeny_t isogeny,
|
||||
elliptic_curve_t E,
|
||||
point_t *points,
|
||||
long num_points,
|
||||
point_t kernel_gen,
|
||||
const mpz_t le) {
|
||||
point_t K;
|
||||
oqs_sidh_iqc_ref_point_init(K);
|
||||
|
||||
oqs_sidh_iqc_ref_point_mul_scaler(K, kernel_gen, le, E);
|
||||
oqs_sidh_iqc_ref_isogeny_compute(isogeny, K);
|
||||
oqs_sidh_iqc_ref_isogeny_evaluate_kohel(kernel_gen, isogeny, kernel_gen);
|
||||
|
||||
for (long i = 0; i < num_points; i++) {
|
||||
oqs_sidh_iqc_ref_isogeny_evaluate_kohel(points[i], isogeny, points[i]);
|
||||
}
|
||||
|
||||
oqs_sidh_iqc_ref_elliptic_curve_set(E, isogeny->codomain);
|
||||
oqs_sidh_iqc_ref_elliptic_curve_set(isogeny->domain, isogeny->codomain);
|
||||
|
||||
oqs_sidh_iqc_ref_point_clear(K);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_isogeny_evaluate_strategy_rec(elliptic_curve_t E,
|
||||
point_t *points,
|
||||
long num_points,
|
||||
point_t *kernel_gens,
|
||||
long num_gens,
|
||||
long l,
|
||||
long e,
|
||||
float ratio) {
|
||||
|
||||
if (e == 1) {
|
||||
isogeny_t isogeny;
|
||||
|
||||
long kernel_size = (long) pow(l, e);
|
||||
oqs_sidh_iqc_ref_isogeny_init(isogeny, kernel_size);
|
||||
oqs_sidh_iqc_ref_elliptic_curve_set(isogeny->domain, E);
|
||||
oqs_sidh_iqc_ref_isogeny_compute(isogeny, kernel_gens[num_gens - 1]);
|
||||
oqs_sidh_iqc_ref_elliptic_curve_set(E, isogeny->codomain);
|
||||
|
||||
for (long i = 0; i < num_points; i++) {
|
||||
oqs_sidh_iqc_ref_isogeny_evaluate_velu(points[i], isogeny, points[i]);
|
||||
}
|
||||
|
||||
for (long i = 0; i < num_gens - 1; i++) {
|
||||
oqs_sidh_iqc_ref_isogeny_evaluate_velu(kernel_gens[i],
|
||||
isogeny,
|
||||
kernel_gens[i]);
|
||||
}
|
||||
|
||||
oqs_sidh_iqc_ref_isogeny_clear(isogeny);
|
||||
return;
|
||||
}
|
||||
|
||||
long r = (long) (ratio * e);
|
||||
|
||||
mpz_t exponent;
|
||||
mpz_init(exponent);
|
||||
mpz_ui_pow_ui(exponent, l, r);
|
||||
|
||||
oqs_sidh_iqc_ref_point_mul_scaler(kernel_gens[num_gens],
|
||||
kernel_gens[num_gens - 1],
|
||||
exponent, E);
|
||||
|
||||
oqs_sidh_iqc_ref_isogeny_evaluate_strategy_rec(E, points, num_points, kernel_gens,
|
||||
num_gens + 1, l, e - r, ratio);
|
||||
oqs_sidh_iqc_ref_isogeny_evaluate_strategy_rec(E, points, num_points, kernel_gens,
|
||||
num_gens, l, r, ratio);
|
||||
mpz_clear(exponent);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_isogeny_evaluate_strategy(elliptic_curve_t E,
|
||||
point_t *points,
|
||||
long num_points,
|
||||
const point_t kernel_gen,
|
||||
long l,
|
||||
long e,
|
||||
float ratio) {
|
||||
|
||||
point_t *kernel_gens = (point_t *) malloc(e * sizeof(point_t));
|
||||
for (long i = 0; i < e; i++)
|
||||
oqs_sidh_iqc_ref_point_init(kernel_gens[i]);
|
||||
oqs_sidh_iqc_ref_point_set(kernel_gens[0], kernel_gen);
|
||||
|
||||
oqs_sidh_iqc_ref_isogeny_evaluate_strategy_rec(E, points, num_points,
|
||||
kernel_gens, 1, l, e, ratio);
|
||||
|
||||
for (long i = 0; i < e; i++)
|
||||
oqs_sidh_iqc_ref_point_clear(kernel_gens[i]);
|
||||
free(kernel_gens);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_isogeny_evaluate_strategy_curve(elliptic_curve_t E,
|
||||
const point_t kernel_gen,
|
||||
long l,
|
||||
long e,
|
||||
float ratio) {
|
||||
oqs_sidh_iqc_ref_isogeny_evaluate_strategy(E, NULL, 0, kernel_gen, l, e, ratio);
|
||||
}
|
232
src/kex_sidh_iqc_ref/sidh_isogeny.h
Normal file
232
src/kex_sidh_iqc_ref/sidh_isogeny.h
Normal file
@ -0,0 +1,232 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ISOGENY_H
|
||||
#define ISOGENY_H
|
||||
|
||||
#include "sidh_elliptic_curve.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Representation of an isogeny between two elliptic curve
|
||||
*/
|
||||
typedef struct {
|
||||
// Let the kernel K of the isogeny (excluding the zero point) be the union
|
||||
// of F and G such that R \in F if and only if -R \in G for all points
|
||||
// R \in K. Then the partition is F.
|
||||
point_t *partition;
|
||||
fp2_element_t *gx;
|
||||
fp2_element_t *gy;
|
||||
fp2_element_t *u;
|
||||
fp2_element_t *v;
|
||||
elliptic_curve_t domain;
|
||||
elliptic_curve_t codomain;
|
||||
long partition_size;
|
||||
long kernel_size;
|
||||
} isogeny_struct;
|
||||
|
||||
typedef isogeny_struct isogeny_t[1];
|
||||
|
||||
/**
|
||||
* Initializes the isogeny {@code isogeny}.
|
||||
* @param isogeny
|
||||
* @param kernel_size
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_isogeny_init(isogeny_t isogeny,
|
||||
long kernel_size);
|
||||
|
||||
/**
|
||||
* Frees the memory allocated to {@code isogeny}.
|
||||
* @param isogeny
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_isogeny_clear(isogeny_t isogeny);
|
||||
|
||||
/**
|
||||
* Computes the isogeny from the kernel generated by {@code kernel_gen}.
|
||||
* @param isogeny
|
||||
* @param kernel_gen
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_isogeny_compute(isogeny_t isogeny,
|
||||
const point_t kernel_gen);
|
||||
|
||||
/**
|
||||
* Evaluates {@code isogeny} at the point {@code P}, using Velu's formulas.
|
||||
* @param Q The result of the evaluation {@code isogeny(P)}
|
||||
* @param isogeny
|
||||
* @param P
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_isogeny_evaluate_velu(point_t Q,
|
||||
const isogeny_t isogeny,
|
||||
const point_t P);
|
||||
|
||||
/**
|
||||
* Evaluates {@code isogeny} at the point {@code P}, using Kohel's formulas.
|
||||
* @param Q The result of the evaluation {@code isogeny(P)}
|
||||
* @param isogeny
|
||||
* @param P
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_isogeny_evaluate_kohel(point_t Q,
|
||||
const isogeny_t isogeny,
|
||||
const point_t P);
|
||||
|
||||
/**
|
||||
* Computes the partition for the isogeny generated by {@code kernel_gen}.
|
||||
* @see isogeny_struct.
|
||||
* @param partition
|
||||
* @param partition_size
|
||||
* @param kernel_gen
|
||||
* @param E
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_isogeny_partition_kernel(point_t *partition,
|
||||
long partition_size,
|
||||
const point_t kernel_gen,
|
||||
const elliptic_curve_t E);
|
||||
|
||||
/**
|
||||
* Sets the kernel size for {@code isogeny}. The new kernel size is assumed
|
||||
* to be smaller than the current kernel size.
|
||||
* @param isogeny
|
||||
* @param kernel_size
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_isogeny_set_kernel_size(isogeny_t isogeny,
|
||||
long kernel_size);
|
||||
|
||||
/**
|
||||
* Computes the images of the elliptic curve {@code E} and the points
|
||||
* {@code points} through the isogeny with kernel generated by the point
|
||||
* {@code kernel_gen}. The size of the kernel is {@code l^e}.
|
||||
* @param E
|
||||
* @param points
|
||||
* @param num_points
|
||||
* @param kernel_gen
|
||||
* @param l
|
||||
* @param e the length of the chain of l-isogenies
|
||||
* @param isogeny_jump the number of successive l-isogenies that should
|
||||
* be computed at once. For example, if {@code isogeny_jump = 2} then a
|
||||
* chain of l-isogenies of length e is computed by doing e / 2 {l^2-isogenies}.
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_isogeny_evaluate_naive(elliptic_curve_t E,
|
||||
point_t *points,
|
||||
long num_points,
|
||||
const point_t kernel_gen,
|
||||
long l,
|
||||
long e,
|
||||
long isogeny_jump);
|
||||
|
||||
/**
|
||||
* Computes the images of the elliptic curve {@code E} through the isogeny
|
||||
* with kernel generated by the point {@code kernel_gen}.
|
||||
* {@link oqs_sidh_iqc_ref_isogeny_evaluate_naive}
|
||||
* @param E
|
||||
* @param kernel_gen
|
||||
* @param l
|
||||
* @param e
|
||||
* @param isogeny_jump
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_isogeny_evaluate_naive_curve(elliptic_curve_t E,
|
||||
const point_t kernel_gen,
|
||||
long l,
|
||||
long e,
|
||||
long isogeny_jump);
|
||||
|
||||
/**
|
||||
* A helper method for {@link oqs_sidh_iqc_ref_isogeny_evaluate_naive}. All the arguments except
|
||||
* {@code num_points, le} will be pushed through the isogeny. For example
|
||||
* {@code E} will be the codomain of the isogeny. This method should not be
|
||||
* called directly.
|
||||
* @param isogeny
|
||||
* @param E
|
||||
* @param points
|
||||
* @param num_points
|
||||
* @param kernel_gen
|
||||
* @param le
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_isogeny_evaluate_naive_helper(isogeny_t isogeny,
|
||||
elliptic_curve_t E,
|
||||
point_t *points,
|
||||
long num_points,
|
||||
point_t kernel_gen,
|
||||
const mpz_t le);
|
||||
|
||||
/**
|
||||
* The recursion for {@link oqs_sidh_iqc_ref_isogeny_evaluate_strategy}.
|
||||
* @param E
|
||||
* @param points see {@link oqs_sidh_iqc_ref_isogeny_evaluate_strategy}
|
||||
* @param num_points see {@link oqs_sidh_iqc_ref_isogeny_evaluate_strategy}
|
||||
* @param kernel_gens contains the previous kernels computed while going down
|
||||
* the recursion tree.
|
||||
* @param num_gens number of elements in {@code kernel_gens}
|
||||
* @param l
|
||||
* @param e
|
||||
* @param ratio see {@link oqs_sidh_iqc_ref_isogeny_evaluate_strategy}
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_isogeny_evaluate_strategy_rec(elliptic_curve_t E,
|
||||
point_t *points,
|
||||
long num_points,
|
||||
point_t *kernel_gens,
|
||||
long num_gens,
|
||||
long l,
|
||||
long e,
|
||||
float ratio);
|
||||
|
||||
/**
|
||||
* This method implements the optimal strategy approach proposed in the paper
|
||||
* De Feo, Luca, David Jao, and Jérôme Plût. "Towards quantum-resistant
|
||||
* cryptosystems from supersingular elliptic curve isogenies".
|
||||
* @param E
|
||||
* @param points the points to be evaluated through the isogeny
|
||||
* @param num_points number of points in {@code points}
|
||||
* @param kernel_gen the generator of the kernel of the isogeny
|
||||
* @param l
|
||||
* @param e
|
||||
* @param ratio a float in the range (0, 1). This indicates the portions of
|
||||
* the computation that is done through point multiplication and isogeny
|
||||
* evaluation. The larger values of {@code ratio} means more multiplication
|
||||
* and less isogeny evaluation.
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_isogeny_evaluate_strategy(elliptic_curve_t E,
|
||||
point_t *points,
|
||||
long num_points,
|
||||
const point_t kernel_gen,
|
||||
long l,
|
||||
long e,
|
||||
float ratio);
|
||||
|
||||
/**
|
||||
* The same as {@link oqs_sidh_iqc_ref_isogeny_evaluate_strategy} except there is no point
|
||||
* to evaluate through the isogeny. This method simply calls
|
||||
* {@link oqs_sidh_iqc_ref_isogeny_evaluate_strategy} with {@code points = NULL, num_points = 0}.
|
||||
* @param E
|
||||
* @param kernel_gen
|
||||
* @param l
|
||||
* @param e
|
||||
* @param ratio
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_isogeny_evaluate_strategy_curve(elliptic_curve_t E,
|
||||
const point_t kernel_gen,
|
||||
long l,
|
||||
long e,
|
||||
float ratio);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ISOGENY_H */
|
102
src/kex_sidh_iqc_ref/sidh_private_key.c
Normal file
102
src/kex_sidh_iqc_ref/sidh_private_key.c
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "sidh_private_key.h"
|
||||
#include "sidh_util.h"
|
||||
#include "sidh_public_param.h"
|
||||
#include <stdio.h>
|
||||
|
||||
void oqs_sidh_iqc_ref_private_key_init(private_key_t private_key) {
|
||||
mpz_inits(private_key->m, private_key->n, NULL);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_private_key_clear(private_key_t private_key) {
|
||||
mpz_clears(private_key->m, private_key->n, NULL);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_private_key_generate(private_key_t private_key,
|
||||
const public_params_t params) {
|
||||
gmp_randstate_t randstate;
|
||||
gmp_randinit_default(randstate);
|
||||
mpz_t seed;
|
||||
mpz_init(seed);
|
||||
oqs_sidh_iqc_ref_get_random_mpz(seed);
|
||||
gmp_randseed(randstate, seed);
|
||||
|
||||
while (1) {
|
||||
mpz_urandomm(private_key->m, randstate, params->le);
|
||||
mpz_urandomm(private_key->n, randstate, params->le);
|
||||
|
||||
if (!mpz_divisible_ui_p(private_key->m, params->l))
|
||||
break;
|
||||
|
||||
if (!mpz_divisible_ui_p(private_key->n, params->l)) {
|
||||
mpz_swap(private_key->m, private_key->n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gmp_randclear(randstate);
|
||||
mpz_clear(seed);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_private_key_compute_kernel_gen(
|
||||
point_t gen, const private_key_t private_key, const point_t P,
|
||||
const point_t Q, const mpz_t le, const elliptic_curve_t E) {
|
||||
mpz_t temp_m;
|
||||
mpz_t temp_n;
|
||||
mpz_init_set(temp_m, private_key->m);
|
||||
mpz_init_set(temp_n, private_key->n);
|
||||
|
||||
point_t result;
|
||||
oqs_sidh_iqc_ref_point_init(result);
|
||||
|
||||
mpz_invert(temp_m, temp_m, le);
|
||||
mpz_mul(temp_n, temp_m, temp_n);
|
||||
mpz_mod(temp_n, temp_n, le);
|
||||
|
||||
oqs_sidh_iqc_ref_point_mul_scaler(result, Q, temp_n, E);
|
||||
oqs_sidh_iqc_ref_point_add(result, result, P, E);
|
||||
oqs_sidh_iqc_ref_point_set(gen, result);
|
||||
|
||||
mpz_clears(temp_m, temp_n, NULL);
|
||||
oqs_sidh_iqc_ref_point_clear(result);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_private_key_print(const private_key_t private_key) {
|
||||
printf("m: %s\n", mpz_get_str(NULL, 10, private_key->m));
|
||||
printf("n: %s\n", mpz_get_str(NULL, 10, private_key->n));
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_private_key_to_bytes(uint8_t *bytes,
|
||||
const private_key_t private_key,
|
||||
long prime_size) {
|
||||
for (long i = 0; i < 2 * prime_size; i++)
|
||||
bytes[i] = 0;
|
||||
|
||||
mpz_export(bytes, NULL, -1, 1, 0, 0, private_key->m);
|
||||
mpz_export(bytes + prime_size, NULL, -1, 1, 0, 0, private_key->n);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_bytes_to_private_key(private_key_t private_key,
|
||||
const uint8_t *bytes,
|
||||
long prime_size) {
|
||||
mpz_set_ui(private_key->m, 0);
|
||||
mpz_set_ui(private_key->n, 0);
|
||||
mpz_import(private_key->m, prime_size, -1, 1, 0, 0, bytes);
|
||||
mpz_import(private_key->n, prime_size, -1, 1, 0, 0, bytes + prime_size);
|
||||
}
|
106
src/kex_sidh_iqc_ref/sidh_private_key.h
Normal file
106
src/kex_sidh_iqc_ref/sidh_private_key.h
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PRIVATE_KEY_H
|
||||
#define PRIVATE_KEY_H
|
||||
|
||||
#include "sidh_elliptic_curve.h"
|
||||
#include "sidh_public_param.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Representation of the private key in oqs_sidh_iqc_ref
|
||||
*/
|
||||
typedef struct {
|
||||
mpz_t m;
|
||||
mpz_t n;
|
||||
} private_key_struct;
|
||||
|
||||
typedef private_key_struct private_key_t[1];
|
||||
|
||||
/**
|
||||
* Initializes the private-key.
|
||||
* @param private_key
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_private_key_init(private_key_t private_key);
|
||||
|
||||
/**
|
||||
* Frees the memory allocated to the private-key.
|
||||
* @param private_key
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_private_key_clear(private_key_t private_key);
|
||||
|
||||
/**
|
||||
* Generates the private-key. It is guaranteed that {@code private_key->m}
|
||||
* is comprime to {@code params->l}.
|
||||
* @param private_key
|
||||
* @param params
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_private_key_generate(private_key_t private_key,
|
||||
const public_params_t params);
|
||||
|
||||
/**
|
||||
* Computes a generator for th kernel generated by {@code gen = m * P + n * Q}.
|
||||
* It is assumed that {@code m} is invertible modulo {@code le}.
|
||||
* @param gen
|
||||
* @param P one of the generators of the l^e torsion.
|
||||
* @param Q one of the generators of the l^e torsion.
|
||||
* @param private_key
|
||||
* @param le
|
||||
* @param E
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_private_key_compute_kernel_gen(point_t gen,
|
||||
const private_key_t private_key,
|
||||
const point_t P,
|
||||
const point_t Q,
|
||||
const mpz_t le,
|
||||
const elliptic_curve_t E);
|
||||
|
||||
/**
|
||||
* Converts a private-key to an array of bytes.
|
||||
* @param bytes
|
||||
* @param private_key
|
||||
* @param prime_size
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_private_key_to_bytes(uint8_t *bytes,
|
||||
const private_key_t private_key,
|
||||
long prime_size);
|
||||
|
||||
/**
|
||||
* Converts an array of bytes to a private-key.
|
||||
* @param private_key
|
||||
* @param bytes
|
||||
* @param prime_size
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_bytes_to_private_key(private_key_t private_key,
|
||||
const uint8_t *bytes,
|
||||
long prime_size);
|
||||
|
||||
/**
|
||||
* Prints {@code private_key} to the standard output.
|
||||
* @param private_key
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_private_key_print(const private_key_t private_key);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PRIVATE_KEY_H */
|
113
src/kex_sidh_iqc_ref/sidh_public_key.c
Normal file
113
src/kex_sidh_iqc_ref/sidh_public_key.c
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "sidh_public_key.h"
|
||||
#include "sidh_isogeny.h"
|
||||
#include "sidh_private_key.h"
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
void oqs_sidh_iqc_ref_public_key_init(public_key_t public_key) {
|
||||
oqs_sidh_iqc_ref_elliptic_curve_init(public_key->E);
|
||||
oqs_sidh_iqc_ref_point_init(public_key->P);
|
||||
oqs_sidh_iqc_ref_point_init(public_key->Q);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_public_key_clear(public_key_t public_key) {
|
||||
oqs_sidh_iqc_ref_elliptic_curve_clear(public_key->E);
|
||||
oqs_sidh_iqc_ref_point_clear(public_key->P);
|
||||
oqs_sidh_iqc_ref_point_clear(public_key->Q);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_public_key_generate(public_key_t public_key,
|
||||
const point_t kernel_gen,
|
||||
const public_params_t paramsA,
|
||||
const public_params_t paramsB) {
|
||||
|
||||
point_t points[2];
|
||||
oqs_sidh_iqc_ref_point_init(points[0]);
|
||||
oqs_sidh_iqc_ref_point_init(points[1]);
|
||||
|
||||
oqs_sidh_iqc_ref_elliptic_curve_set(public_key->E, paramsA->E);
|
||||
oqs_sidh_iqc_ref_point_set(points[0], paramsB->P);
|
||||
oqs_sidh_iqc_ref_point_set(points[1], paramsB->Q);
|
||||
|
||||
oqs_sidh_iqc_ref_isogeny_evaluate_strategy(public_key->E,
|
||||
points,
|
||||
2,
|
||||
kernel_gen,
|
||||
paramsA->l,
|
||||
paramsA->e,
|
||||
0.5);
|
||||
|
||||
// oqs_sidh_iqc_ref_isogeny_evaluate_naive(public_key->E,
|
||||
// points,
|
||||
// 2,
|
||||
// kernel_gen,
|
||||
// paramsA->l,
|
||||
// paramsA->e,
|
||||
// 10);
|
||||
|
||||
oqs_sidh_iqc_ref_point_set(public_key->P, points[0]);
|
||||
oqs_sidh_iqc_ref_point_set(public_key->Q, points[1]);
|
||||
|
||||
oqs_sidh_iqc_ref_point_clear(points[0]);
|
||||
oqs_sidh_iqc_ref_point_clear(points[1]);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_public_key_print(const public_key_t public_key) {
|
||||
printf("E: %s\n", oqs_sidh_iqc_ref_elliptic_curve_get_str(public_key->E));
|
||||
printf("P: %s\n", oqs_sidh_iqc_ref_point_get_str(public_key->P));
|
||||
printf("Q: %s\n", oqs_sidh_iqc_ref_point_get_str(public_key->Q));
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_public_key_to_bytes(uint8_t *bytes,
|
||||
const public_key_t public_key,
|
||||
long prime_size) {
|
||||
long index = 0;
|
||||
oqs_sidh_iqc_ref_fp2_to_bytes(bytes + index, public_key->E->a, prime_size);
|
||||
index += 2 * prime_size;
|
||||
oqs_sidh_iqc_ref_fp2_to_bytes(bytes + index, public_key->E->b, prime_size);
|
||||
index += 2 * prime_size;
|
||||
oqs_sidh_iqc_ref_fp2_to_bytes(bytes + index, public_key->P->x, prime_size);
|
||||
index += 2 * prime_size;
|
||||
oqs_sidh_iqc_ref_fp2_to_bytes(bytes + index, public_key->P->y, prime_size);
|
||||
index += 2 * prime_size;
|
||||
oqs_sidh_iqc_ref_fp2_to_bytes(bytes + index, public_key->Q->x, prime_size);
|
||||
index += 2 * prime_size;
|
||||
oqs_sidh_iqc_ref_fp2_to_bytes(bytes + index, public_key->Q->y, prime_size);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_bytes_to_public_key(public_key_t public_key,
|
||||
const uint8_t *bytes,
|
||||
long prime_size) {
|
||||
long index = 0;
|
||||
oqs_sidh_iqc_ref_bytes_to_fp2(public_key->E->a, bytes + index, prime_size);
|
||||
index += 2 * prime_size;
|
||||
oqs_sidh_iqc_ref_bytes_to_fp2(public_key->E->b, bytes + index, prime_size);
|
||||
index += 2 * prime_size;
|
||||
oqs_sidh_iqc_ref_bytes_to_fp2(public_key->P->x, bytes + index, prime_size);
|
||||
index += 2 * prime_size;
|
||||
oqs_sidh_iqc_ref_bytes_to_fp2(public_key->P->y, bytes + index, prime_size);
|
||||
index += 2 * prime_size;
|
||||
oqs_sidh_iqc_ref_bytes_to_fp2(public_key->Q->x, bytes + index, prime_size);
|
||||
index += 2 * prime_size;
|
||||
oqs_sidh_iqc_ref_bytes_to_fp2(public_key->Q->y, bytes + index, prime_size);
|
||||
|
||||
public_key->P->z = 1;
|
||||
public_key->Q->z = 1;
|
||||
}
|
94
src/kex_sidh_iqc_ref/sidh_public_key.h
Normal file
94
src/kex_sidh_iqc_ref/sidh_public_key.h
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PUBLIC_KEY_H
|
||||
#define PUBLIC_KEY_H
|
||||
|
||||
#include "sidh_public_param.h"
|
||||
#include "sidh_private_key.h"
|
||||
#include "sidh_isogeny.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Representation of the public key in oqs_sidh_iqc_ref
|
||||
*/
|
||||
typedef struct {
|
||||
elliptic_curve_t E;
|
||||
point_t P;
|
||||
point_t Q;
|
||||
} public_key_struct;
|
||||
|
||||
typedef public_key_struct public_key_t[1];
|
||||
|
||||
/**
|
||||
* Initializes the public-key.
|
||||
* @param public_key
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_public_key_init(public_key_t public_key);
|
||||
|
||||
/**
|
||||
* Frees the memory allocated to the public-key.
|
||||
* @param public_key
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_public_key_clear(public_key_t public_key);
|
||||
|
||||
/**
|
||||
* Generates the public-key
|
||||
* @param public_key
|
||||
* @param kernel_gen a generator for the kernel of the isogeny
|
||||
* @param paramsA own params
|
||||
* @param paramsB other's params
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_public_key_generate(public_key_t public_key,
|
||||
const point_t kernel_gen,
|
||||
const public_params_t paramsA,
|
||||
const public_params_t paramsB);
|
||||
|
||||
/**
|
||||
* Prints {@code public_key} to the standard output.
|
||||
* @param public_key
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_public_key_print(const public_key_t public_key);
|
||||
|
||||
/**
|
||||
* Converts a public-key to a byte array.
|
||||
* @param bytes
|
||||
* @param public_key
|
||||
* @param prime_size
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_public_key_to_bytes(uint8_t *bytes,
|
||||
const public_key_t public_key,
|
||||
long prime_size);
|
||||
|
||||
/**
|
||||
* Converts a byte array to a public-key.
|
||||
* @param public_key
|
||||
* @param bytes
|
||||
* @param prime_size
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_bytes_to_public_key(public_key_t public_key,
|
||||
const uint8_t *bytes,
|
||||
long prime_size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PUBLIC_KEY_H */
|
158
src/kex_sidh_iqc_ref/sidh_public_key_encryption.c
Normal file
158
src/kex_sidh_iqc_ref/sidh_public_key_encryption.c
Normal file
@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "sidh_public_key_encryption.h"
|
||||
#include "sidh_public_key.h"
|
||||
#include "sidh_util.h"
|
||||
#include "sidh_shared_key.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void oqs_sidh_iqc_ref_public_key_ciphertext_init(ciphertext_t ciphertext) {
|
||||
oqs_sidh_iqc_ref_elliptic_curve_init(ciphertext->E);
|
||||
oqs_sidh_iqc_ref_point_init(ciphertext->P);
|
||||
oqs_sidh_iqc_ref_point_init(ciphertext->Q);
|
||||
ciphertext->size = 0;
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_public_key_ciphertext_clear(ciphertext_t ciphertext) {
|
||||
oqs_sidh_iqc_ref_elliptic_curve_clear(ciphertext->E);
|
||||
oqs_sidh_iqc_ref_point_clear(ciphertext->P);
|
||||
oqs_sidh_iqc_ref_point_clear(ciphertext->Q);
|
||||
free(ciphertext->content);
|
||||
ciphertext->size = 0;
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_public_key_plaintext_init(plaintext_t plaintext) {
|
||||
plaintext->size = 0;
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_public_key_plaintext_clear(plaintext_t plaintext) {
|
||||
plaintext->size = 0;
|
||||
}
|
||||
|
||||
int oqs_sidh_iqc_ref_public_key_pad_plaintext(plaintext_t result,
|
||||
const plaintext_t raw) {
|
||||
long key_size = public_key_get_key_size();
|
||||
long max_msg_size = key_size - 1;
|
||||
|
||||
if (raw->size > key_size) {
|
||||
printf("\nMessage too large. It should be less than %ld bytes.\n",
|
||||
max_msg_size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// pad the message
|
||||
char *new_content = (char *) malloc(max_msg_size);
|
||||
memset(new_content, 0, max_msg_size);
|
||||
memcpy(new_content, raw->content, raw->size);
|
||||
|
||||
result->content = new_content;
|
||||
result->size = max_msg_size;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_public_key_encrypt(ciphertext_t ciphertext,
|
||||
const plaintext_t plaintext,
|
||||
const public_key_t public_keyA,
|
||||
const public_params_t paramsA,
|
||||
const public_params_t paramsB) {
|
||||
|
||||
private_key_t private_key_temp;
|
||||
oqs_sidh_iqc_ref_private_key_init(private_key_temp);
|
||||
oqs_sidh_iqc_ref_private_key_generate(private_key_temp, paramsB);
|
||||
|
||||
point_t kernel_gen;
|
||||
oqs_sidh_iqc_ref_point_init(kernel_gen);
|
||||
oqs_sidh_iqc_ref_private_key_compute_kernel_gen(kernel_gen,
|
||||
private_key_temp,
|
||||
paramsB->P,
|
||||
paramsB->Q,
|
||||
paramsB->le,
|
||||
paramsB->E);
|
||||
|
||||
public_key_t public_key_temp;
|
||||
oqs_sidh_iqc_ref_public_key_init(public_key_temp);
|
||||
oqs_sidh_iqc_ref_public_key_generate(public_key_temp, kernel_gen, paramsB, paramsA);
|
||||
|
||||
fp2_element_t shared_key;
|
||||
oqs_sidh_iqc_ref_fp2_init(shared_key);
|
||||
oqs_sidh_iqc_ref_shared_key_generate(shared_key, public_keyA, private_key_temp, paramsB);
|
||||
char *hash = oqs_sidh_iqc_ref_public_key_encryption_hash(shared_key, plaintext->size);
|
||||
|
||||
ciphertext->content = oqs_sidh_iqc_ref_array_xor(plaintext->content,
|
||||
hash, plaintext->size);
|
||||
ciphertext->size = plaintext->size;
|
||||
oqs_sidh_iqc_ref_elliptic_curve_set(ciphertext->E, public_key_temp->E);
|
||||
oqs_sidh_iqc_ref_point_set(ciphertext->P, public_key_temp->P);
|
||||
oqs_sidh_iqc_ref_point_set(ciphertext->Q, public_key_temp->Q);
|
||||
|
||||
oqs_sidh_iqc_ref_private_key_clear(private_key_temp);
|
||||
oqs_sidh_iqc_ref_point_clear(kernel_gen);
|
||||
oqs_sidh_iqc_ref_public_key_clear(public_key_temp);
|
||||
oqs_sidh_iqc_ref_fp2_clear(shared_key);
|
||||
free(hash);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_public_key_decrypt(plaintext_t plaintext,
|
||||
const ciphertext_t ciphertext,
|
||||
const private_key_t private_keyA,
|
||||
const public_params_t paramsA) {
|
||||
|
||||
public_key_t public_key_temp;
|
||||
oqs_sidh_iqc_ref_public_key_init(public_key_temp);
|
||||
oqs_sidh_iqc_ref_elliptic_curve_set(public_key_temp->E, ciphertext->E);
|
||||
oqs_sidh_iqc_ref_point_set(public_key_temp->P, ciphertext->P);
|
||||
oqs_sidh_iqc_ref_point_set(public_key_temp->Q, ciphertext->Q);
|
||||
|
||||
fp2_element_t shared_key;
|
||||
oqs_sidh_iqc_ref_fp2_init(shared_key);
|
||||
oqs_sidh_iqc_ref_shared_key_generate(shared_key, public_key_temp, private_keyA, paramsA);
|
||||
char *hash = oqs_sidh_iqc_ref_public_key_encryption_hash(shared_key, ciphertext->size);
|
||||
|
||||
plaintext->content = oqs_sidh_iqc_ref_array_xor(ciphertext->content, hash,
|
||||
ciphertext->size);
|
||||
plaintext->size = ciphertext->size;
|
||||
|
||||
oqs_sidh_iqc_ref_public_key_clear(public_key_temp);
|
||||
oqs_sidh_iqc_ref_fp2_clear(shared_key);
|
||||
free(hash);
|
||||
}
|
||||
|
||||
const mp_limb_t *mpz_limbs_read(const mpz_t x);
|
||||
|
||||
char *oqs_sidh_iqc_ref_public_key_encryption_hash(const fp2_element_t value,
|
||||
long size) {
|
||||
// compute the size of value in chars
|
||||
long size_a = labs(mpz_size(value->a)) * sizeof(mp_limb_t);
|
||||
long size_b = labs(mpz_size(value->b)) * sizeof(mp_limb_t);
|
||||
|
||||
char *hash = (char *) malloc(size);
|
||||
|
||||
memcpy(hash, (char *) mpz_limbs_read(value->a), size_a);
|
||||
memcpy(hash + size_a, (char *) mpz_limbs_read(value->b), size_b);
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
long public_key_get_key_size() {
|
||||
// the key size is twice as large as the base prime.
|
||||
long key_size = 2 * labs(mpz_size(characteristic)) * sizeof(mp_limb_t);
|
||||
return key_size;
|
||||
}
|
132
src/kex_sidh_iqc_ref/sidh_public_key_encryption.h
Normal file
132
src/kex_sidh_iqc_ref/sidh_public_key_encryption.h
Normal file
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PUBLIC_KEY_ENCRYPTION_H
|
||||
#define PUBLIC_KEY_ENCRYPTION_H
|
||||
|
||||
#include "sidh_elliptic_curve.h"
|
||||
#include "sidh_public_key.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Representation of ciphertext in oqs_sidh_iqc_ref
|
||||
*/
|
||||
typedef struct {
|
||||
elliptic_curve_t E;
|
||||
point_t P;
|
||||
point_t Q;
|
||||
char *content;
|
||||
|
||||
// size of the content field
|
||||
long size;
|
||||
} ciphertext_struct;
|
||||
|
||||
/**
|
||||
* Representation of plaintext in oqs_sidh_iqc_ref
|
||||
*/
|
||||
typedef struct {
|
||||
char *content;
|
||||
|
||||
// size of the content field
|
||||
long size;
|
||||
} plaintext_struct;
|
||||
|
||||
typedef ciphertext_struct ciphertext_t[1];
|
||||
typedef plaintext_struct plaintext_t[1];
|
||||
|
||||
/**
|
||||
* Initializes the ciphertext.
|
||||
* @param ciphertext
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_public_key_ciphertext_init(ciphertext_t ciphertext);
|
||||
|
||||
/**
|
||||
* Frees the memory allocated to {@code ciphertext}.
|
||||
* @param ciphertext
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_public_key_ciphertext_clear(ciphertext_t ciphertext);
|
||||
|
||||
/**
|
||||
* Initializes the plaintext.
|
||||
* @param plaintext
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_public_key_plaintext_init(plaintext_t plaintext);
|
||||
|
||||
/**
|
||||
* Frees the memory allocated to {@code plaintext}.
|
||||
* @param plaintext
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_public_key_plaintext_clear(plaintext_t plaintext);
|
||||
|
||||
/**
|
||||
* Pads a given plain text for encryption.
|
||||
* @param result the prepared plaintext
|
||||
* @param raw the given plaintext
|
||||
* @return 1 if successful, and -1 otherwise
|
||||
*/
|
||||
int oqs_sidh_iqc_ref_public_key_pad_plaintext(plaintext_t result,
|
||||
const plaintext_t raw);
|
||||
|
||||
/**
|
||||
* Encrypts the {@code plaintext} using {@code public_key}.
|
||||
* @param ciphertext the generated cipher
|
||||
* @param plaintext
|
||||
* @param public_keyA other's public-key
|
||||
* @param paramsA other's public params
|
||||
* @param paramsB own pubic params
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_public_key_encrypt(ciphertext_t ciphertext,
|
||||
const plaintext_t plaintext,
|
||||
const public_key_t public_keyA,
|
||||
const public_params_t paramsA,
|
||||
const public_params_t paramsB);
|
||||
|
||||
/**
|
||||
* Decrypts the {@code ciphertext} using {@code private_key}.
|
||||
* @param plaintext the result
|
||||
* @param ciphertext the given ciphertext
|
||||
* @param private_keyA
|
||||
* @param paramsA the public parameters associated to the owner of
|
||||
* the private-key
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_public_key_decrypt(plaintext_t plaintext,
|
||||
const ciphertext_t ciphertext,
|
||||
const private_key_t private_keyA,
|
||||
const public_params_t paramsA);
|
||||
|
||||
/**
|
||||
* Computes the hash of {@code value}
|
||||
* @param value
|
||||
* @param size size of the output hash
|
||||
* @return the hash
|
||||
*/
|
||||
char *oqs_sidh_iqc_ref_public_key_encryption_hash(const fp2_element_t value,
|
||||
long size);
|
||||
|
||||
/**
|
||||
* @return the key-size in bytes
|
||||
*/
|
||||
long public_key_get_key_size();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PUBLIC_KEY_ENCRYPTION_H */
|
106
src/kex_sidh_iqc_ref/sidh_public_key_validation.c
Normal file
106
src/kex_sidh_iqc_ref/sidh_public_key_validation.c
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "sidh_public_key_validation.h"
|
||||
#include "sidh_elliptic_curve_dlp.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int oqs_sidh_iqc_ref_public_key_is_valid(const public_key_t public_key,
|
||||
const public_params_t params) {
|
||||
if (!oqs_sidh_iqc_ref_public_key_check_order(public_key->P, public_key->E, params))
|
||||
return 0;
|
||||
|
||||
if (!oqs_sidh_iqc_ref_public_key_check_order(public_key->Q, public_key->E, params))
|
||||
return 0;
|
||||
|
||||
if (!oqs_sidh_iqc_ref_public_key_check_dependency(public_key, params))
|
||||
return 0;
|
||||
|
||||
if (!oqs_sidh_iqc_ref_public_key_check_curve(public_key->E))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int oqs_sidh_iqc_ref_public_key_check_order(const point_t P,
|
||||
const elliptic_curve_t E,
|
||||
const public_params_t params) {
|
||||
mpz_t order;
|
||||
point_t temp;
|
||||
|
||||
mpz_init_set(order, params->le);
|
||||
oqs_sidh_iqc_ref_point_init(temp);
|
||||
|
||||
int result = 0;
|
||||
mpz_divexact_ui(order, order, params->l);
|
||||
oqs_sidh_iqc_ref_point_mul_scaler(temp, P, order, E);
|
||||
if (!oqs_sidh_iqc_ref_point_is_zero(temp)) {
|
||||
oqs_sidh_iqc_ref_point_mul_scaler_si(temp, temp, params->l, E);
|
||||
if (oqs_sidh_iqc_ref_point_is_zero(temp))
|
||||
result = 1;
|
||||
}
|
||||
|
||||
mpz_clear(order);
|
||||
oqs_sidh_iqc_ref_point_clear(temp);
|
||||
return result;
|
||||
}
|
||||
|
||||
int oqs_sidh_iqc_ref_public_key_check_dependency(const public_key_t public_key,
|
||||
const public_params_t params) {
|
||||
mpz_t x;
|
||||
mpz_init(x);
|
||||
|
||||
int result = 0;
|
||||
oqs_sidh_iqc_ref_elliptic_curve_prime_power_dlp(x,
|
||||
public_key->P,
|
||||
public_key->Q,
|
||||
public_key->E,
|
||||
params->l,
|
||||
params->e);
|
||||
|
||||
if (mpz_cmp_si(x, -1) == 0) {
|
||||
oqs_sidh_iqc_ref_elliptic_curve_prime_power_dlp(x,
|
||||
public_key->Q,
|
||||
public_key->P,
|
||||
public_key->E,
|
||||
params->l,
|
||||
params->e);
|
||||
if (mpz_cmp_si(x, -1) == 0)
|
||||
result = 1;
|
||||
}
|
||||
|
||||
mpz_clear(x);
|
||||
return result;
|
||||
}
|
||||
|
||||
int oqs_sidh_iqc_ref_public_key_check_curve(const elliptic_curve_t E) {
|
||||
point_t temp;
|
||||
mpz_t exponent;
|
||||
|
||||
oqs_sidh_iqc_ref_point_init(temp);
|
||||
mpz_init_set(exponent, characteristic);
|
||||
mpz_add_ui(exponent, exponent, 1);
|
||||
|
||||
oqs_sidh_iqc_ref_elliptic_curve_random_point(temp, E);
|
||||
oqs_sidh_iqc_ref_point_mul_scaler(temp, temp, exponent, E);
|
||||
int result = oqs_sidh_iqc_ref_point_is_zero(temp);
|
||||
|
||||
oqs_sidh_iqc_ref_point_clear(temp);
|
||||
mpz_clear(exponent);
|
||||
|
||||
return result;
|
||||
}
|
72
src/kex_sidh_iqc_ref/sidh_public_key_validation.h
Normal file
72
src/kex_sidh_iqc_ref/sidh_public_key_validation.h
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PUBLIC_KEY_VALIDATION_H
|
||||
#define PUBLIC_KEY_VALIDATION_H
|
||||
|
||||
#include "sidh_elliptic_curve.h"
|
||||
#include "sidh_public_key.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Check if a given public-key is valid.
|
||||
* @param public_key
|
||||
* @param params the other party's public parameters from which
|
||||
* the public-key is generated.
|
||||
* @return 1 if the public-key is valid, 0 otherwise
|
||||
*/
|
||||
int oqs_sidh_iqc_ref_public_key_is_valid(const public_key_t public_key,
|
||||
const public_params_t params);
|
||||
|
||||
/**
|
||||
* Checks if {@code P} has the exact order l^e where l, e are given in
|
||||
* {@code params}.
|
||||
* @param P
|
||||
* @param E
|
||||
* @param params
|
||||
* @return 1 if {@code P} has order l^e, 0 otherwise
|
||||
*/
|
||||
int oqs_sidh_iqc_ref_public_key_check_order(const point_t P,
|
||||
const elliptic_curve_t E,
|
||||
const public_params_t params);
|
||||
|
||||
/**
|
||||
* Checks if the two point in {@code public-key} are linearly independent.
|
||||
* @param public_key
|
||||
* @param params
|
||||
* @return 1 if the points are linearly independent, 0 otherwise
|
||||
*/
|
||||
int oqs_sidh_iqc_ref_public_key_check_dependency(const public_key_t public_key,
|
||||
const public_params_t params);
|
||||
|
||||
/**
|
||||
* Checks if a given is valid supersingular curve. A curve is considered
|
||||
* valid if it has order (p + 1)^2 where p is the characteristic. The test
|
||||
* is done probabilistically.
|
||||
* @param E
|
||||
* @return 1 if the curve is valid, 0 otherwise.
|
||||
*/
|
||||
int oqs_sidh_iqc_ref_public_key_check_curve(const elliptic_curve_t E);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PUBLIC_KEY_VALIDATION_H */
|
100
src/kex_sidh_iqc_ref/sidh_public_param.c
Normal file
100
src/kex_sidh_iqc_ref/sidh_public_param.c
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "sidh_public_param.h"
|
||||
|
||||
void oqs_sidh_iqc_ref_public_params_init(public_params_t params) {
|
||||
mpz_init(params->characteristic);
|
||||
oqs_sidh_iqc_ref_elliptic_curve_init(params->E);
|
||||
oqs_sidh_iqc_ref_point_init(params->P);
|
||||
oqs_sidh_iqc_ref_point_init(params->Q);
|
||||
mpz_init(params->le);
|
||||
}
|
||||
|
||||
int oqs_sidh_iqc_ref_public_params_read(public_params_t paramsA,
|
||||
public_params_t paramsB,
|
||||
const char *file_name) {
|
||||
FILE *input;
|
||||
input = fopen(file_name, "r");
|
||||
if (!input) {
|
||||
printf("No such file!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
fp2_element_t a;
|
||||
fp2_element_t b;
|
||||
oqs_sidh_iqc_ref_fp2_init(a);
|
||||
oqs_sidh_iqc_ref_fp2_init(b);
|
||||
|
||||
gmp_fscanf(input, "p : %Zd \n", paramsA->characteristic);
|
||||
mpz_set(paramsB->characteristic, paramsA->characteristic);
|
||||
gmp_fscanf(input,
|
||||
"E : y^2 = x^3 + (%Zd * i + %Zd) * x + (%Zd * i + %Zd) \n",
|
||||
a->a, a->b, b->a, b->b);
|
||||
oqs_sidh_iqc_ref_elliptic_curve_set_coeffs(paramsA->E, a, b);
|
||||
oqs_sidh_iqc_ref_elliptic_curve_set(paramsB->E, paramsA->E);
|
||||
gmp_fscanf(input, "lA: %ld \n", ¶msA->l);
|
||||
gmp_fscanf(input, "eA: %ld \n", ¶msA->e);
|
||||
mpz_ui_pow_ui(paramsA->le, paramsA->l, paramsA->e);
|
||||
gmp_fscanf(input,
|
||||
"PA: (%Zd * i + %Zd, %Zd * i + %Zd) \n",
|
||||
a->a, a->b, b->a, b->b);
|
||||
oqs_sidh_iqc_ref_point_set_coordinates(paramsA->P, a, b, 1);
|
||||
gmp_fscanf(input,
|
||||
"QA: (%Zd * i + %Zd, %Zd * i + %Zd) \n",
|
||||
a->a, a->b, b->a, b->b);
|
||||
oqs_sidh_iqc_ref_point_set_coordinates(paramsA->Q, a, b, 1);
|
||||
gmp_fscanf(input, "lB: %ld \n", ¶msB->l);
|
||||
gmp_fscanf(input, "eB: %ld \n", ¶msB->e);
|
||||
mpz_ui_pow_ui(paramsB->le, paramsB->l, paramsB->e);
|
||||
gmp_fscanf(input,
|
||||
"PB: (%Zd * i + %Zd, %Zd * i + %Zd) \n",
|
||||
a->a, a->b, b->a, b->b);
|
||||
oqs_sidh_iqc_ref_point_set_coordinates(paramsB->P, a, b, 1);
|
||||
gmp_fscanf(input,
|
||||
"QB: (%Zd * i + %Zd, %Zd * i + %Zd) \n",
|
||||
a->a, a->b, b->a, b->b);
|
||||
oqs_sidh_iqc_ref_point_set_coordinates(paramsB->Q, a, b, 1);
|
||||
|
||||
fclose(input);
|
||||
oqs_sidh_iqc_ref_fp2_clear(a);
|
||||
oqs_sidh_iqc_ref_fp2_clear(b);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_public_params_print(const public_params_t params,
|
||||
int print_torsion) {
|
||||
if (print_torsion != 1) {
|
||||
printf("p : %s\n", mpz_get_str(NULL, 10, params->characteristic));
|
||||
printf("E : %s\n", oqs_sidh_iqc_ref_elliptic_curve_get_str(params->E));
|
||||
}
|
||||
|
||||
printf("lA: %ld\n", params->l);
|
||||
printf("eA: %ld\n", params->e);
|
||||
printf("PA: %s\n", oqs_sidh_iqc_ref_point_get_str(params->P));
|
||||
printf("QA: %s\n", oqs_sidh_iqc_ref_point_get_str(params->Q));
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_public_params_clear(public_params_t params) {
|
||||
mpz_clear(params->characteristic);
|
||||
oqs_sidh_iqc_ref_elliptic_curve_clear(params->E);
|
||||
oqs_sidh_iqc_ref_point_clear(params->P);
|
||||
oqs_sidh_iqc_ref_point_clear(params->Q);
|
||||
mpz_clear(params->le);
|
||||
}
|
85
src/kex_sidh_iqc_ref/sidh_public_param.h
Normal file
85
src/kex_sidh_iqc_ref/sidh_public_param.h
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PUBLIC_PARAM_H
|
||||
#define PUBLIC_PARAM_H
|
||||
|
||||
#include "sidh_elliptic_curve.h"
|
||||
#include "sidh_quadratic_ext.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Representation of the public parameters in oqs_sidh_iqc_ref
|
||||
*/
|
||||
typedef struct {
|
||||
// the characteristic
|
||||
mpz_t characteristic;
|
||||
|
||||
elliptic_curve_t E;
|
||||
unsigned long l;
|
||||
unsigned long e;
|
||||
|
||||
// a generator for the l^e torsion subgroup of E
|
||||
point_t P;
|
||||
point_t Q;
|
||||
|
||||
// l^e, precomputed
|
||||
mpz_t le;
|
||||
|
||||
} public_params_struct;
|
||||
|
||||
typedef public_params_struct public_params_t[1];
|
||||
|
||||
/**
|
||||
* Initializes the public parameters.
|
||||
* @param params
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_public_params_init(public_params_t params);
|
||||
|
||||
/**
|
||||
* Reads the public parameters from file named {@code file_name}.
|
||||
* @param paramsA
|
||||
* @param paramsB
|
||||
* @param file_name
|
||||
* @return 1 if the parameters are read successfully, and 0 otherwise.
|
||||
*/
|
||||
int oqs_sidh_iqc_ref_public_params_read(public_params_t paramsA,
|
||||
public_params_t paramsB,
|
||||
const char *file_name);
|
||||
|
||||
/**
|
||||
* Prints the public parameters to the standard output.
|
||||
* @param params
|
||||
* @param torsion if it is 1 only the torsion parameters are printed
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_public_params_print(const public_params_t params,
|
||||
int print_torsion);
|
||||
|
||||
/**
|
||||
* Frees the memory allocated to {@code params}.
|
||||
* @param params
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_public_params_clear(public_params_t params);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PUBLIC_PARAM_H */
|
443
src/kex_sidh_iqc_ref/sidh_quadratic_ext.c
Normal file
443
src/kex_sidh_iqc_ref/sidh_quadratic_ext.c
Normal file
@ -0,0 +1,443 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "sidh_quadratic_ext.h"
|
||||
#include "sidh_util.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void oqs_sidh_iqc_ref_fp_init_chararacteristic_ui(long p) {
|
||||
mpz_init_set_ui(characteristic, p);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_fp_init_chararacteristic_str(const char *value) {
|
||||
mpz_init_set_str(characteristic, value, 10);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_fp_init_chararacteristic(const mpz_t p) {
|
||||
mpz_init_set(characteristic, p);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_fp_set(mpz_t x, const mpz_t a) {
|
||||
mpz_mod(x, a, characteristic);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_fp_add(mpz_t x, const mpz_t a, const mpz_t b) {
|
||||
mpz_add(x, a, b);
|
||||
mpz_mod(x, x, characteristic);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_fp_add_ui(mpz_t x, const mpz_t a, unsigned long b) {
|
||||
mpz_add_ui(x, a, b);
|
||||
mpz_mod(x, x, characteristic);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_fp_sub(mpz_t x, const mpz_t a, const mpz_t b) {
|
||||
mpz_sub(x, a, b);
|
||||
mpz_mod(x, x, characteristic);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_fp_sub_ui(mpz_t x, const mpz_t a, unsigned long b) {
|
||||
mpz_sub_ui(x, a, b);
|
||||
mpz_mod(x, x, characteristic);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_fp_mul(mpz_t x, const mpz_t a, const mpz_t b) {
|
||||
mpz_mul(x, a, b);
|
||||
mpz_mod(x, x, characteristic);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_fp_mul_si(mpz_t x, const mpz_t a, long b) {
|
||||
mpz_mul_si(x, a, b);
|
||||
mpz_mod(x, x, characteristic);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_fp_inv(mpz_t x, const mpz_t a) {
|
||||
mpz_invert(x, a, characteristic);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_fp_div(mpz_t x, const mpz_t a, const mpz_t b) {
|
||||
oqs_sidh_iqc_ref_fp_inv(x, b);
|
||||
oqs_sidh_iqc_ref_fp_mul(x, a, x);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_fp_neg(mpz_t x, const mpz_t a) {
|
||||
oqs_sidh_iqc_ref_fp_sub(x, characteristic, a);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_fp_sqrt(mpz_t x, const mpz_t a) {
|
||||
mpz_t exponent;
|
||||
mpz_init(exponent);
|
||||
|
||||
// compute (p + 1) / 4
|
||||
mpz_add_ui(exponent, characteristic, 1);
|
||||
mpz_divexact_ui(exponent, exponent, 4);
|
||||
|
||||
mpz_powm(x, a, exponent, characteristic);
|
||||
mpz_clear(exponent);
|
||||
}
|
||||
|
||||
//////////////// fp2 methods //////////////////////////
|
||||
|
||||
void oqs_sidh_iqc_ref_fp2_init(fp2_element_t x) { mpz_inits(x->a, x->b, NULL); }
|
||||
|
||||
void oqs_sidh_iqc_ref_fp2_init_set_si(fp2_element_t x, long a, long b) {
|
||||
mpz_init_set_si(x->a, a);
|
||||
mpz_init_set_si(x->b, b);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_fp2_init_set_str(fp2_element_t x, const char *a,
|
||||
const char *b) {
|
||||
mpz_init_set_str(x->a, a, 10);
|
||||
mpz_init_set_str(x->b, b, 10);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_fp2_init_set(fp2_element_t x, const fp2_element_t a) {
|
||||
mpz_init_set(x->a, a->a);
|
||||
mpz_init_set(x->b, a->b);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_fp2_clear(fp2_element_t x) {
|
||||
mpz_clears(x->a, x->b, NULL);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_fp2_set(fp2_element_t x, const fp2_element_t b) {
|
||||
mpz_set(x->a, b->a);
|
||||
mpz_set(x->b, b->b);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_fp2_zero(fp2_element_t x) {
|
||||
mpz_set_si(x->a, 0);
|
||||
mpz_set_si(x->b, 0);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_fp2_one(fp2_element_t x) {
|
||||
mpz_set_si(x->a, 0);
|
||||
mpz_set_si(x->b, 1);
|
||||
}
|
||||
|
||||
char *oqs_sidh_iqc_ref_fp2_get_str(const fp2_element_t a) {
|
||||
|
||||
if (mpz_cmp_si(a->a, 0) == 0 && mpz_cmp_si(a->b, 0) == 0) {
|
||||
return "0";
|
||||
}
|
||||
|
||||
if (mpz_cmp_si(a->a, 0) == 0) {
|
||||
return mpz_get_str(NULL, 10, a->b);
|
||||
}
|
||||
|
||||
char *result = "";
|
||||
|
||||
if (mpz_cmp_si(a->b, 0) == 0) {
|
||||
result = oqs_sidh_iqc_ref_concat(result, mpz_get_str(NULL, 10, a->a));
|
||||
result = oqs_sidh_iqc_ref_concat(result, " * i");
|
||||
return result;
|
||||
}
|
||||
|
||||
result = oqs_sidh_iqc_ref_concat(result, mpz_get_str(NULL, 10, a->a));
|
||||
result = oqs_sidh_iqc_ref_concat(result, " * i + ");
|
||||
result = oqs_sidh_iqc_ref_concat(result, mpz_get_str(NULL, 10, a->b));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_fp2_add(fp2_element_t x, const fp2_element_t a,
|
||||
const fp2_element_t b) {
|
||||
oqs_sidh_iqc_ref_fp_add(x->a, a->a, b->a);
|
||||
oqs_sidh_iqc_ref_fp_add(x->b, a->b, b->b);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_fp2_add_ui(fp2_element_t x, const fp2_element_t a,
|
||||
unsigned long b) {
|
||||
oqs_sidh_iqc_ref_fp_add_ui(x->b, a->b, b);
|
||||
oqs_sidh_iqc_ref_fp_set(x->a, a->a);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_fp2_sub(fp2_element_t x, const fp2_element_t a,
|
||||
const fp2_element_t b) {
|
||||
oqs_sidh_iqc_ref_fp_sub(x->a, a->a, b->a);
|
||||
oqs_sidh_iqc_ref_fp_sub(x->b, a->b, b->b);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_fp2_sub_ui(fp2_element_t x, const fp2_element_t a,
|
||||
unsigned long b) {
|
||||
oqs_sidh_iqc_ref_fp_sub_ui(x->b, a->b, b);
|
||||
oqs_sidh_iqc_ref_fp_set(x->a, a->a);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_fp2_mul(fp2_element_t x, const fp2_element_t a,
|
||||
const fp2_element_t b) {
|
||||
mpz_t temp1;
|
||||
mpz_t temp2;
|
||||
|
||||
mpz_init(temp1);
|
||||
mpz_init(temp2);
|
||||
|
||||
fp2_element_t result;
|
||||
oqs_sidh_iqc_ref_fp2_init(result);
|
||||
|
||||
// (a + b) * (c + d)
|
||||
oqs_sidh_iqc_ref_fp_add(temp1, a->a, a->b);
|
||||
oqs_sidh_iqc_ref_fp_add(temp2, b->a, b->b);
|
||||
oqs_sidh_iqc_ref_fp_mul(result->a, temp1, temp2);
|
||||
|
||||
// a * c
|
||||
oqs_sidh_iqc_ref_fp_mul(temp1, a->a, b->a);
|
||||
// b * d
|
||||
oqs_sidh_iqc_ref_fp_mul(temp2, a->b, b->b);
|
||||
|
||||
oqs_sidh_iqc_ref_fp_sub(result->a, result->a, temp1);
|
||||
oqs_sidh_iqc_ref_fp_sub(result->a, result->a, temp2);
|
||||
oqs_sidh_iqc_ref_fp_sub(result->b, temp2, temp1);
|
||||
oqs_sidh_iqc_ref_fp2_set(x, result);
|
||||
|
||||
mpz_clear(temp1);
|
||||
mpz_clear(temp2);
|
||||
oqs_sidh_iqc_ref_fp2_clear(result);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_fp2_square(fp2_element_t x, const fp2_element_t a) {
|
||||
mpz_t temp1;
|
||||
mpz_t temp2;
|
||||
|
||||
mpz_init(temp1);
|
||||
mpz_init(temp2);
|
||||
|
||||
fp2_element_t result;
|
||||
oqs_sidh_iqc_ref_fp2_init(result);
|
||||
|
||||
// (b + a) * (b - a)
|
||||
oqs_sidh_iqc_ref_fp_add(temp1, a->a, a->b);
|
||||
oqs_sidh_iqc_ref_fp_sub(temp2, a->b, a->a);
|
||||
oqs_sidh_iqc_ref_fp_mul(result->b, temp1, temp2);
|
||||
|
||||
// 2 * a * b
|
||||
oqs_sidh_iqc_ref_fp_mul(result->a, a->a, a->b);
|
||||
oqs_sidh_iqc_ref_fp_mul_si(result->a, result->a, 2);
|
||||
|
||||
oqs_sidh_iqc_ref_fp2_set(x, result);
|
||||
|
||||
mpz_clear(temp1);
|
||||
mpz_clear(temp2);
|
||||
oqs_sidh_iqc_ref_fp2_clear(result);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_fp2_pow_ui(fp2_element_t x, const fp2_element_t a,
|
||||
unsigned long n) {
|
||||
mpz_t temp_n;
|
||||
mpz_init_set_ui(temp_n, n);
|
||||
oqs_sidh_iqc_ref_fp2_pow(x, a, temp_n);
|
||||
mpz_clear(temp_n);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_fp2_pow(fp2_element_t x, const fp2_element_t a,
|
||||
const mpz_t n) {
|
||||
if (mpz_cmp_ui(n, 0) == 0) {
|
||||
oqs_sidh_iqc_ref_fp2_one(x);
|
||||
return;
|
||||
}
|
||||
|
||||
fp2_element_t temp1;
|
||||
fp2_element_t temp2;
|
||||
oqs_sidh_iqc_ref_fp2_init_set_si(temp1, 0, 1);
|
||||
oqs_sidh_iqc_ref_fp2_init_set(temp2, a);
|
||||
|
||||
long num_bits = mpz_sizeinbase(n, 2);
|
||||
for (long i = 0; i < num_bits; i++) {
|
||||
if (mpz_tstbit(n, i) == 1)
|
||||
oqs_sidh_iqc_ref_fp2_mul(temp1, temp1, temp2);
|
||||
oqs_sidh_iqc_ref_fp2_square(temp2, temp2);
|
||||
}
|
||||
|
||||
oqs_sidh_iqc_ref_fp2_set(x, temp1);
|
||||
|
||||
oqs_sidh_iqc_ref_fp2_clear(temp1);
|
||||
oqs_sidh_iqc_ref_fp2_clear(temp2);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_fp2_conjugate(fp2_element_t x, const fp2_element_t a) {
|
||||
oqs_sidh_iqc_ref_fp2_set(x, a);
|
||||
oqs_sidh_iqc_ref_fp_neg(x->a, x->a);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_fp2_negate(fp2_element_t x, const fp2_element_t a) {
|
||||
oqs_sidh_iqc_ref_fp2_set(x, a);
|
||||
oqs_sidh_iqc_ref_fp_neg(x->a, x->a);
|
||||
oqs_sidh_iqc_ref_fp_neg(x->b, x->b);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_fp2_mul_scaler(fp2_element_t x, const fp2_element_t a,
|
||||
const mpz_t scaler) {
|
||||
oqs_sidh_iqc_ref_fp_mul(x->a, a->a, scaler);
|
||||
oqs_sidh_iqc_ref_fp_mul(x->b, a->b, scaler);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_fp2_mul_scaler_si(fp2_element_t x, const fp2_element_t a,
|
||||
long scaler) {
|
||||
oqs_sidh_iqc_ref_fp_mul_si(x->a, a->a, scaler);
|
||||
oqs_sidh_iqc_ref_fp_mul_si(x->b, a->b, scaler);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_fp2_inv(fp2_element_t x, const fp2_element_t a) {
|
||||
mpz_t temp;
|
||||
fp2_element_t result;
|
||||
|
||||
mpz_init(temp);
|
||||
oqs_sidh_iqc_ref_fp2_init(result);
|
||||
|
||||
oqs_sidh_iqc_ref_fp2_conjugate(result, a);
|
||||
oqs_sidh_iqc_ref_fp2_norm(temp, a);
|
||||
oqs_sidh_iqc_ref_fp_inv(temp, temp);
|
||||
oqs_sidh_iqc_ref_fp2_mul_scaler(result, result, temp);
|
||||
oqs_sidh_iqc_ref_fp2_set(x, result);
|
||||
|
||||
mpz_clear(temp);
|
||||
oqs_sidh_iqc_ref_fp2_clear(result);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_fp2_div(fp2_element_t x, const fp2_element_t a,
|
||||
const fp2_element_t b) {
|
||||
fp2_element_t result;
|
||||
oqs_sidh_iqc_ref_fp2_init(result);
|
||||
|
||||
oqs_sidh_iqc_ref_fp2_inv(result, b);
|
||||
oqs_sidh_iqc_ref_fp2_mul(result, a, result);
|
||||
oqs_sidh_iqc_ref_fp2_set(x, result);
|
||||
|
||||
oqs_sidh_iqc_ref_fp2_clear(result);
|
||||
}
|
||||
|
||||
int oqs_sidh_iqc_ref_fp2_is_zero(const fp2_element_t a) {
|
||||
return !mpz_cmp_si(a->a, 0) && !mpz_cmp_si(a->b, 0);
|
||||
}
|
||||
|
||||
int oqs_sidh_iqc_ref_fp2_is_one(const fp2_element_t a) {
|
||||
return !mpz_cmp_si(a->a, 0) && !mpz_cmp_si(a->b, 1);
|
||||
}
|
||||
|
||||
int oqs_sidh_iqc_ref_fp2_equals(const fp2_element_t a, const fp2_element_t b) {
|
||||
return (mpz_cmp(a->a, b->a) == 0) && (mpz_cmp(a->b, b->b) == 0);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_fp2_random(fp2_element_t x, gmp_randstate_t randstate) {
|
||||
mpz_urandomm(x->a, randstate, characteristic);
|
||||
mpz_urandomm(x->b, randstate, characteristic);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_fp2_sqrt(fp2_element_t x, const fp2_element_t a) {
|
||||
mpz_t exponent;
|
||||
fp2_element_t temp_a;
|
||||
fp2_element_t b;
|
||||
fp2_element_t c;
|
||||
fp2_element_t beta;
|
||||
mpz_t base_root;
|
||||
gmp_randstate_t randstate;
|
||||
|
||||
mpz_init(exponent);
|
||||
oqs_sidh_iqc_ref_fp2_init(temp_a);
|
||||
oqs_sidh_iqc_ref_fp2_init(b);
|
||||
oqs_sidh_iqc_ref_fp2_init(c);
|
||||
oqs_sidh_iqc_ref_fp2_init(beta);
|
||||
mpz_init(base_root);
|
||||
gmp_randinit_default(randstate);
|
||||
|
||||
// compute (p - 1) / 2
|
||||
mpz_sub_ui(exponent, characteristic, 1);
|
||||
mpz_divexact_ui(exponent, exponent, 2);
|
||||
|
||||
while (oqs_sidh_iqc_ref_fp2_is_zero(b)) {
|
||||
oqs_sidh_iqc_ref_fp2_random(c, randstate);
|
||||
oqs_sidh_iqc_ref_fp2_square(temp_a, c);
|
||||
oqs_sidh_iqc_ref_fp2_mul(temp_a, temp_a, a);
|
||||
|
||||
// compute 1 + temp_a^((p - 1) / 2)
|
||||
oqs_sidh_iqc_ref_fp2_pow(b, temp_a, exponent);
|
||||
oqs_sidh_iqc_ref_fp2_add_ui(b, b, 1);
|
||||
}
|
||||
|
||||
// compute temp_a * b^2
|
||||
oqs_sidh_iqc_ref_fp2_square(beta, b);
|
||||
oqs_sidh_iqc_ref_fp2_mul(beta, beta, temp_a);
|
||||
|
||||
// beta is now in the prime field
|
||||
oqs_sidh_iqc_ref_fp_sqrt(base_root, beta->b);
|
||||
oqs_sidh_iqc_ref_fp2_inv(b, b);
|
||||
oqs_sidh_iqc_ref_fp2_mul_scaler(b, b, base_root);
|
||||
oqs_sidh_iqc_ref_fp2_div(x, b, c);
|
||||
|
||||
mpz_clear(exponent);
|
||||
oqs_sidh_iqc_ref_fp2_clear(temp_a);
|
||||
oqs_sidh_iqc_ref_fp2_clear(b);
|
||||
oqs_sidh_iqc_ref_fp2_clear(c);
|
||||
oqs_sidh_iqc_ref_fp2_clear(beta);
|
||||
mpz_clear(base_root);
|
||||
gmp_randclear(randstate);
|
||||
}
|
||||
|
||||
int oqs_sidh_iqc_ref_fp2_is_square(const fp2_element_t a) {
|
||||
mpz_t exponent;
|
||||
mpz_t norm;
|
||||
fp2_element_t temp;
|
||||
|
||||
mpz_init(exponent);
|
||||
mpz_init(norm);
|
||||
oqs_sidh_iqc_ref_fp2_init(temp);
|
||||
|
||||
// a^((p - 1) / 2)
|
||||
mpz_sub_ui(exponent, characteristic, 1);
|
||||
mpz_divexact_ui(exponent, exponent, 2);
|
||||
oqs_sidh_iqc_ref_fp2_pow(temp, a, exponent);
|
||||
|
||||
oqs_sidh_iqc_ref_fp2_norm(norm, temp);
|
||||
int result = (mpz_cmp_si(norm, 1) == 0);
|
||||
|
||||
mpz_clear(exponent);
|
||||
mpz_clear(norm);
|
||||
oqs_sidh_iqc_ref_fp2_clear(temp);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_fp2_norm(mpz_t x, const fp2_element_t a) {
|
||||
mpz_t temp1;
|
||||
mpz_t temp2;
|
||||
mpz_inits(temp1, temp2, NULL);
|
||||
|
||||
oqs_sidh_iqc_ref_fp_mul(temp1, a->a, a->a);
|
||||
oqs_sidh_iqc_ref_fp_mul(temp2, a->b, a->b);
|
||||
oqs_sidh_iqc_ref_fp_add(temp1, temp1, temp2);
|
||||
|
||||
mpz_set(x, temp1);
|
||||
mpz_clears(temp1, temp2, NULL);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_fp2_to_bytes(uint8_t *bytes, const fp2_element_t a,
|
||||
long prime_size) {
|
||||
for (long i = 0; i < 2 * prime_size; i++)
|
||||
bytes[i] = 0;
|
||||
|
||||
mpz_export(bytes, NULL, -1, 1, 0, 0, a->a);
|
||||
mpz_export(bytes + prime_size, NULL, -1, 1, 0, 0, a->b);
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_bytes_to_fp2(fp2_element_t a, const uint8_t *bytes,
|
||||
long prime_size) {
|
||||
oqs_sidh_iqc_ref_fp2_zero(a);
|
||||
mpz_import(a->a, prime_size, -1, 1, 0, 0, bytes);
|
||||
mpz_import(a->b, prime_size, -1, 1, 0, 0, bytes + prime_size);
|
||||
}
|
445
src/kex_sidh_iqc_ref/sidh_quadratic_ext.h
Normal file
445
src/kex_sidh_iqc_ref/sidh_quadratic_ext.h
Normal file
@ -0,0 +1,445 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef FP2_H
|
||||
#define FP2_H
|
||||
|
||||
#include <gmp.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
mpz_t characteristic;
|
||||
|
||||
/**
|
||||
* Representation of elements of the quadratic extension F_(p^2)
|
||||
* of F_p. We assume F_(p^2) is represented by the quotient
|
||||
* F_p[X] / (X^2 + 1) which requires X^2 + 1 to be irreducible over F_p.
|
||||
* The elements are therefore of the form a * i + b where i^2 = -1.
|
||||
*/
|
||||
typedef struct {
|
||||
mpz_t a;
|
||||
mpz_t b;
|
||||
} fp2_element_struct;
|
||||
|
||||
typedef fp2_element_struct fp2_element_t[1];
|
||||
|
||||
//////////////// fp methods //////////////////////////
|
||||
|
||||
/**
|
||||
* {@link oqs_sidh_iqc_ref_init_chararacteristic}
|
||||
* @param p
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp_init_chararacteristic_ui(long p);
|
||||
|
||||
/**
|
||||
* {@link oqs_sidh_iqc_ref_init_chararacteristic}
|
||||
* @param value
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp_init_chararacteristic_str(const char *value);
|
||||
|
||||
/**
|
||||
* Initializes the characteristic to {@code p}.
|
||||
* @param p
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp_init_chararacteristic(const mpz_t p);
|
||||
|
||||
/**
|
||||
* Sets {@code x = a}.
|
||||
* @param x
|
||||
* @param a
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp_set(mpz_t x, const mpz_t a);
|
||||
|
||||
/**
|
||||
* Sets {@code x = a + b}.
|
||||
* @param x
|
||||
* @param a
|
||||
* @param b
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp_add(mpz_t x,
|
||||
const mpz_t a,
|
||||
const mpz_t b);
|
||||
|
||||
/**
|
||||
* {@link oqs_sidh_iqc_ref_fp_add}.
|
||||
* @param x
|
||||
* @param a
|
||||
* @param b
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp_add_ui(mpz_t x,
|
||||
const mpz_t a,
|
||||
unsigned long b);
|
||||
|
||||
/**
|
||||
* Sets {@code x = a - b}.
|
||||
* @param x
|
||||
* @param a
|
||||
* @param b
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp_sub(mpz_t x,
|
||||
const mpz_t a,
|
||||
const mpz_t b);
|
||||
|
||||
/**
|
||||
* {@link oqs_sidh_iqc_ref_fp_sub}
|
||||
* @param x
|
||||
* @param a
|
||||
* @param b
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp_sub_ui(mpz_t x,
|
||||
const mpz_t a,
|
||||
unsigned long b);
|
||||
|
||||
/**
|
||||
* Sets {@code x = a * b}.
|
||||
* @param x
|
||||
* @param a
|
||||
* @param b
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp_mul(mpz_t x,
|
||||
const mpz_t a,
|
||||
const mpz_t b);
|
||||
|
||||
/**
|
||||
* {@link oqs_sidh_iqc_ref_fp_mul}
|
||||
* @param x
|
||||
* @param a
|
||||
* @param b
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp_mul_si(mpz_t x,
|
||||
const mpz_t a,
|
||||
long b);
|
||||
|
||||
/**
|
||||
* Sets {@code x = 1 / a}. This is possible only if {@code a} is
|
||||
* prime to the characteristic.
|
||||
* @param x
|
||||
* @param a
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp_inv(mpz_t x,
|
||||
const mpz_t a);
|
||||
|
||||
/**
|
||||
* Sets {x = a / b}. @see fp_inv.
|
||||
* @param x
|
||||
* @param a
|
||||
* @param b
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp_div(mpz_t x,
|
||||
const mpz_t a,
|
||||
const mpz_t b);
|
||||
|
||||
/**
|
||||
* Sets {@code x = -a}.
|
||||
* @param x
|
||||
* @param a
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp_neg(mpz_t x,
|
||||
const mpz_t a);
|
||||
|
||||
/**
|
||||
* Computes the square root of {@code a}.
|
||||
* This method works only for p = 3 mod 4.
|
||||
* @param x the square root
|
||||
* @param a
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp_sqrt(mpz_t x,
|
||||
const mpz_t a);
|
||||
|
||||
//////////////// fp2 methods //////////////////////////
|
||||
|
||||
/**
|
||||
* Initializes {@code x} to zero.
|
||||
* @param x
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp2_init(fp2_element_t x);
|
||||
|
||||
/**
|
||||
* Initializes {@code x} to {@code a * i + b}.
|
||||
* @param x
|
||||
* @param a
|
||||
* @param b
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp2_init_set_si(fp2_element_t x,
|
||||
long a,
|
||||
long b);
|
||||
|
||||
/**
|
||||
* {@link oqs_sidh_iqc_ref_fp2_init_set_si}.
|
||||
* @param x
|
||||
* @param a
|
||||
* @param b
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp2_init_set_str(fp2_element_t x,
|
||||
const char *a,
|
||||
const char *b);
|
||||
|
||||
/**
|
||||
* Initializes {@code x} to {@code a}.
|
||||
* @param x
|
||||
* @param a
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp2_init_set(fp2_element_t x,
|
||||
const fp2_element_t a);
|
||||
|
||||
/**
|
||||
* Frees the memory allocated to {@code x}.
|
||||
* @param x
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp2_clear(fp2_element_t x);
|
||||
|
||||
/**
|
||||
* Copies {@code a} into {@code x}.
|
||||
* @param x
|
||||
* @param b
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp2_set(fp2_element_t x,
|
||||
const fp2_element_t b);
|
||||
|
||||
/**
|
||||
* Sets {@code a = 0}
|
||||
* @param x
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp2_zero(fp2_element_t x);
|
||||
|
||||
/**
|
||||
* Sets {@code x = 1}.
|
||||
* @param x
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp2_one(fp2_element_t x);
|
||||
|
||||
/**
|
||||
* @param a
|
||||
* @return the string representation of {@code a}
|
||||
*/
|
||||
char *oqs_sidh_iqc_ref_fp2_get_str(const fp2_element_t a);
|
||||
|
||||
/**
|
||||
* Sets {@code x = a + b}.
|
||||
* @param x
|
||||
* @param a
|
||||
* @param b
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp2_add(fp2_element_t x,
|
||||
const fp2_element_t a,
|
||||
const fp2_element_t b);
|
||||
|
||||
/**
|
||||
* {@link oqs_sidh_iqc_ref_fp2_add}
|
||||
* @param x
|
||||
* @param a
|
||||
* @param b
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp2_add_ui(fp2_element_t x,
|
||||
const fp2_element_t a,
|
||||
unsigned long b);
|
||||
|
||||
/**
|
||||
* Sets {@code x = a - b}.
|
||||
* @param x
|
||||
* @param a
|
||||
* @param b
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp2_sub(fp2_element_t x,
|
||||
const fp2_element_t a,
|
||||
const fp2_element_t b);
|
||||
|
||||
/**
|
||||
* {@link oqs_sidh_iqc_ref_fp2_sub}
|
||||
* @param x
|
||||
* @param a
|
||||
* @param b
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp2_sub_ui(fp2_element_t x,
|
||||
const fp2_element_t a,
|
||||
unsigned long b);
|
||||
|
||||
/**
|
||||
* Sets {@code x = a * b}.
|
||||
* @param x
|
||||
* @param a
|
||||
* @param b
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp2_mul(fp2_element_t x,
|
||||
const fp2_element_t a,
|
||||
const fp2_element_t b);
|
||||
|
||||
/**
|
||||
* Sets {@code x = a^2}.
|
||||
* @param x
|
||||
* @param a
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp2_square(fp2_element_t x,
|
||||
const fp2_element_t a);
|
||||
|
||||
/**
|
||||
* {@link oqs_sidh_iqc_ref_fp2_pow}
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp2_pow_ui(fp2_element_t x,
|
||||
const fp2_element_t a,
|
||||
unsigned long n);
|
||||
|
||||
/**
|
||||
* Sets {@code x = a^n}.
|
||||
* @param x
|
||||
* @param a
|
||||
* @param n
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp2_pow(fp2_element_t x,
|
||||
const fp2_element_t a,
|
||||
const mpz_t n);
|
||||
|
||||
/**
|
||||
* Sets {@code x = 1 / a}.
|
||||
* @param x
|
||||
* @param a
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp2_inv(fp2_element_t x,
|
||||
const fp2_element_t a);
|
||||
|
||||
/**
|
||||
* Sets {@code x = a / b}.
|
||||
* @param x
|
||||
* @param a
|
||||
* @param b
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp2_div(fp2_element_t x,
|
||||
const fp2_element_t a,
|
||||
const fp2_element_t b);
|
||||
|
||||
/**
|
||||
* Sets {@code x = -u * i + v} where {@code a = u * i + v}.
|
||||
* @param x
|
||||
* @param a
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp2_conjugate(fp2_element_t x,
|
||||
const fp2_element_t a);
|
||||
|
||||
/**
|
||||
* Sets {@code x = -a}.
|
||||
* @param x
|
||||
* @param a
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp2_negate(fp2_element_t x,
|
||||
const fp2_element_t a);
|
||||
|
||||
/**
|
||||
* Sets {@code x = a * scaler}.
|
||||
* @param x
|
||||
* @param a
|
||||
* @param scaler
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp2_mul_scaler(fp2_element_t x,
|
||||
const fp2_element_t a,
|
||||
const mpz_t scaler);
|
||||
|
||||
/**
|
||||
* {@link oqs_sidh_iqc_ref_fp2_mul_scaler}
|
||||
* @param x
|
||||
* @param a
|
||||
* @param scaler
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp2_mul_scaler_si(fp2_element_t x,
|
||||
const fp2_element_t a,
|
||||
long scaler);
|
||||
|
||||
/**
|
||||
* Checks if {@code a} is zero.
|
||||
* @param a
|
||||
* @return 1 if {@code a == 0}, and 0 otherwise
|
||||
*/
|
||||
int oqs_sidh_iqc_ref_fp2_is_zero(const fp2_element_t a);
|
||||
|
||||
/**
|
||||
* Checks if {@code a} is one.
|
||||
* @param a
|
||||
* @return 1 if {@code a == 1}, and 0 otherwise
|
||||
*/
|
||||
int oqs_sidh_iqc_ref_fp2_is_one(const fp2_element_t a);
|
||||
|
||||
/**
|
||||
* Checks if {@code a == b}.
|
||||
* @param a
|
||||
* @param b
|
||||
* @return 1 if {@code a == b}, and 0 otherwise.
|
||||
*/
|
||||
int oqs_sidh_iqc_ref_fp2_equals(const fp2_element_t a,
|
||||
const fp2_element_t b);
|
||||
|
||||
/**
|
||||
* Generates a random element in the quadratic extension.
|
||||
* @param x the generated random element
|
||||
* @param randstate
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp2_random(fp2_element_t x,
|
||||
gmp_randstate_t randstate);
|
||||
|
||||
/**
|
||||
* Computes the square root of {@code a}.
|
||||
* The algorithm is based on
|
||||
* Doliskani & Schost, Taking Roots over High Extensions of Finite Fields, 2011.
|
||||
* It works for any characteristic, but since it uses {@link oqs_sidh_iqc_ref_fp_sqrt} for
|
||||
* base-case square root, it is limited to p = 3 mod 4.
|
||||
* @param x the square root
|
||||
* @param a
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp2_sqrt(fp2_element_t x,
|
||||
const fp2_element_t a);
|
||||
|
||||
/**
|
||||
* Checks if {@code a} is a square.
|
||||
* @param a
|
||||
* @return 1 if {@code a} is a square, 0 otherwise
|
||||
*/
|
||||
int oqs_sidh_iqc_ref_fp2_is_square(const fp2_element_t a);
|
||||
|
||||
/**
|
||||
* Computes the norm of {@code x = b * i + c} which is b^2 + c^2.
|
||||
* @param x the computed norm
|
||||
* @param a
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp2_norm(mpz_t x,
|
||||
const fp2_element_t a);
|
||||
|
||||
/**
|
||||
* Converts bytes an fp2 element to a byte array.
|
||||
* @param bytes
|
||||
* @param a
|
||||
* @param prime_size
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_fp2_to_bytes(uint8_t *bytes,
|
||||
const fp2_element_t a,
|
||||
long prime_size);
|
||||
|
||||
/**
|
||||
* Converts a byte array to an fp2 element.
|
||||
* @param a
|
||||
* @param bytes
|
||||
* @param prime_size
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_bytes_to_fp2(fp2_element_t a,
|
||||
const uint8_t *bytes,
|
||||
long prime_size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FP2_H */
|
47
src/kex_sidh_iqc_ref/sidh_shared_key.c
Normal file
47
src/kex_sidh_iqc_ref/sidh_shared_key.c
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "sidh_shared_key.h"
|
||||
#include "sidh_isogeny.h"
|
||||
|
||||
void oqs_sidh_iqc_ref_shared_key_generate(fp2_element_t shared_key,
|
||||
const public_key_t public_key,
|
||||
const private_key_t private_key,
|
||||
const public_params_t params) {
|
||||
|
||||
point_t kernel_gen;
|
||||
oqs_sidh_iqc_ref_point_init(kernel_gen);
|
||||
|
||||
// compute a generator for the kernel of the isogeny
|
||||
oqs_sidh_iqc_ref_private_key_compute_kernel_gen(kernel_gen,
|
||||
private_key,
|
||||
public_key->P,
|
||||
public_key->Q,
|
||||
params->le,
|
||||
public_key->E);
|
||||
elliptic_curve_t E;
|
||||
oqs_sidh_iqc_ref_elliptic_curve_init(E);
|
||||
oqs_sidh_iqc_ref_elliptic_curve_set(E, public_key->E);
|
||||
|
||||
oqs_sidh_iqc_ref_isogeny_evaluate_strategy_curve(E, kernel_gen, params->l, params->e, 0.5);
|
||||
// oqs_sidh_iqc_ref_isogeny_evaluate_naive_curve(E, kernel_gen, params->l, params->e, 3);
|
||||
|
||||
oqs_sidh_iqc_ref_elliptic_curve_compute_j_inv(shared_key, E);
|
||||
|
||||
oqs_sidh_iqc_ref_point_clear(kernel_gen);
|
||||
oqs_sidh_iqc_ref_elliptic_curve_clear(E);
|
||||
}
|
44
src/kex_sidh_iqc_ref/sidh_shared_key.h
Normal file
44
src/kex_sidh_iqc_ref/sidh_shared_key.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SHARED_KEY_H
|
||||
#define SHARED_KEY_H
|
||||
|
||||
#include "sidh_private_key.h"
|
||||
#include "sidh_public_key.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Generates the shared-key.
|
||||
* @param shared_key the generated shared-key
|
||||
* @param public_key other's public-key
|
||||
* @param private_key own private-key
|
||||
* @param params own parameters
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_shared_key_generate(fp2_element_t shared_key,
|
||||
const public_key_t public_key,
|
||||
const private_key_t private_key,
|
||||
const public_params_t params);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SHARED_KEY_H */
|
54
src/kex_sidh_iqc_ref/sidh_util.c
Normal file
54
src/kex_sidh_iqc_ref/sidh_util.c
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <gmp.h>
|
||||
#include <time.h>
|
||||
#include <oqs/rand.h>
|
||||
|
||||
#include "sidh_util.h"
|
||||
|
||||
char *oqs_sidh_iqc_ref_concat(char *str1, const char *str2) {
|
||||
char *temp = (char *) malloc(strlen(str1) + strlen(str2) + 1);
|
||||
strcpy(temp, str1);
|
||||
strcat(temp, str2);
|
||||
return temp;
|
||||
}
|
||||
|
||||
char *oqs_sidh_iqc_ref_get_random_str(int num_bytes) {
|
||||
char *rand_value = (char *) malloc(num_bytes);
|
||||
OQS_RAND *rand = OQS_RAND_new(OQS_RAND_alg_urandom_chacha20);
|
||||
OQS_RAND_n(rand, (uint8_t *) rand_value, num_bytes);
|
||||
|
||||
return rand_value;
|
||||
}
|
||||
|
||||
void oqs_sidh_iqc_ref_get_random_mpz(mpz_t x) {
|
||||
int num_bytes = 20;
|
||||
char *a = oqs_sidh_iqc_ref_get_random_str(num_bytes);
|
||||
mpz_import(x, num_bytes, 1, sizeof(char), 0, 0, a);
|
||||
}
|
||||
|
||||
char *oqs_sidh_iqc_ref_array_xor(const char *array1, const char *array2,
|
||||
long lenght) {
|
||||
char *result = (char *) malloc(lenght);
|
||||
for (long i = 0; i < lenght; i++)
|
||||
result[i] = array1[i] ^ array2[i];
|
||||
|
||||
return result;
|
||||
}
|
62
src/kex_sidh_iqc_ref/sidh_util.h
Normal file
62
src/kex_sidh_iqc_ref/sidh_util.h
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Javad Doliskani, javad.doliskani@uwaterloo.ca
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef UTIL_H
|
||||
#define UTIL_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Concatenates two strings.
|
||||
* @param str1
|
||||
* @param str2
|
||||
* @return the concatenation of {@code str1, str2}
|
||||
*/
|
||||
char *oqs_sidh_iqc_ref_concat(char *str1,
|
||||
const char *str2);
|
||||
|
||||
/**
|
||||
* Generates a random char array of length {@code num_bytes}.
|
||||
* @param num_bytes
|
||||
* @return a random char array of length {@code num_bytes}
|
||||
*/
|
||||
char *oqs_sidh_iqc_ref_get_random_str(int num_bytes);
|
||||
|
||||
/**
|
||||
* @param x a randomly generated 160bit integer
|
||||
*/
|
||||
void oqs_sidh_iqc_ref_get_random_mpz(mpz_t x);
|
||||
|
||||
/**
|
||||
* @param array1
|
||||
* @param array2
|
||||
* @param lenght
|
||||
* @return the bitwise xor of the two arrays
|
||||
*/
|
||||
char *oqs_sidh_iqc_ref_array_xor(const char *array1,
|
||||
const char *array2,
|
||||
long lenght);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* UTIL_H */
|
Loading…
x
Reference in New Issue
Block a user