Prettyprint

This commit is contained in:
Christian Paquin 2020-03-03 16:50:56 -05:00
parent d2a46900d7
commit 2ea7cf173a
13 changed files with 2437 additions and 2338 deletions

View File

@ -32,14 +32,14 @@
//
const uint64_t p434[NWORDS64_FIELD] = {0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFDC1767AE2FFFFFF,
0x7BC65C783158AEA3, 0x6CFC5FD681C52056, 0x0002341F27177344
};
0x7BC65C783158AEA3, 0x6CFC5FD681C52056, 0x0002341F27177344
};
const uint64_t p434p1[NWORDS64_FIELD] = {0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFDC1767AE3000000,
0x7BC65C783158AEA3, 0x6CFC5FD681C52056, 0x0002341F27177344
};
0x7BC65C783158AEA3, 0x6CFC5FD681C52056, 0x0002341F27177344
};
const uint64_t p434x2[NWORDS64_FIELD] = {0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFB82ECF5C5FFFFFF,
0xF78CB8F062B15D47, 0xD9F8BFAD038A40AC, 0x0004683E4E2EE688
};
0xF78CB8F062B15D47, 0xD9F8BFAD038A40AC, 0x0004683E4E2EE688
};
// Order of Alice's subgroup
static const uint64_t Alice_order[NWORDS64_ORDER] = {0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000001000000};
// Order of Bob's subgroup

View File

@ -1,145 +1,154 @@
/********************************************************************************************
* SIDH: an efficient supersingular isogeny cryptography library
*
* Abstract: supersingular isogeny parameters and generation of functions for P503
*********************************************************************************************/
#include <oqs/rand.h>
#include "../oqs_namespace_sike.h"
#include "P503_api.h"
#include "P503_internal.h"
// defines moved from P503_api.h
#define CRYPTO_SECRETKEYBYTES 434 // MSG_BYTES + SECRETKEY_B_BYTES + CRYPTO_PUBLICKEYBYTES bytes
#define CRYPTO_PUBLICKEYBYTES 378
#define CRYPTO_BYTES 24
#define CRYPTO_CIPHERTEXTBYTES 402 // CRYPTO_PUBLICKEYBYTES + MSG_BYTES bytes
#define SIDH_SECRETKEYBYTES_A 32
#define SIDH_SECRETKEYBYTES_B 32
#define SIDH_PUBLICKEYBYTES 378
#define SIDH_BYTES 126
// Encoding of field elements, elements over Z_order, elements over GF(p^2) and elliptic curve points:
// --------------------------------------------------------------------------------------------------
// Elements over GF(p) and Z_order are encoded with the least significant octet (and digit) located at the leftmost position (i.e., little endian format).
// Elements (a+b*i) over GF(p^2), where a and b are defined over GF(p), are encoded as {a, b}, with a in the least significant position.
// Elliptic curve points P = (x,y) are encoded as {x, y}, with x in the least significant position.
// Internally, the number of digits used to represent all these elements is obtained by approximating the number of bits to the immediately greater multiple of 32.
// For example, a 503-bit field element is represented with Ceil(503 / 64) = 8 64-bit digits or Ceil(503 / 32) = 16 32-bit digits.
//
// Curve isogeny system "SIDHp503". Base curve: Montgomery curve By^2 = Cx^3 + Ax^2 + Cx defined over GF(p503^2), where A=6, B=1, C=1 and p503 = 2^250*3^159-1
//
const uint64_t p503[NWORDS64_FIELD] = {0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xABFFFFFFFFFFFFFF,
0x13085BDA2211E7A0, 0x1B9BF6C87B7E7DAF, 0x6045C6BDDA77A4D0, 0x004066F541811E1E};
const uint64_t p503p1[NWORDS64_FIELD] = {0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xAC00000000000000,
0x13085BDA2211E7A0, 0x1B9BF6C87B7E7DAF, 0x6045C6BDDA77A4D0, 0x004066F541811E1E};
const uint64_t p503x2[NWORDS64_FIELD] = {0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x57FFFFFFFFFFFFFF,
0x2610B7B44423CF41, 0x3737ED90F6FCFB5E, 0xC08B8D7BB4EF49A0, 0x0080CDEA83023C3C};
// Order of Alice's subgroup
static const uint64_t Alice_order[NWORDS64_ORDER] = {0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0400000000000000};
// Order of Bob's subgroup
static const uint64_t Bob_order[NWORDS64_ORDER] = {0xC216F6888479E82B, 0xE6FDB21EDF9F6BC4, 0x1171AF769DE93406, 0x1019BD5060478798};
// Alice's generator values {XPA0 + XPA1*i, XQA0 + XQA1*i, XRA0 + XRA1*i} in GF(p503^2), expressed in Montgomery representation
static const uint64_t A_gen[6 * NWORDS64_FIELD] = {0x5D083011589AD893, 0xADFD8D2CB67D0637, 0x330C9AC34FFB6361, 0xF0D47489A2E805A2,
0x27E2789259C6B8DC, 0x63866A2C121931B9, 0x8D4C65A7137DCF44, 0x003A183AE5967B3F, // XPA0
0x7E3541B8C96D1519, 0xD3ADAEEC0D61A26C, 0xC0A2219CE7703DD9, 0xFF3E46658FCDBC52,
0xD5B38DEAE6E196FF, 0x1AAC826364956D58, 0xEC9F4875B9A5F27A, 0x001B0B475AB99843, // XPA1
0x4D83695107D03BAD, 0x221F3299005E2FCF, 0x78E6AE22F30DECF2, 0x6D982DB5111253E4,
0x504C80A8AB4526A8, 0xEFD0C3AA210BB024, 0xCB77483501DC6FCF, 0x001052544A96BDF3, // XQA0
0x0D74FE3402BCAE47, 0xDF5B8CDA832D8AED, 0xB86BCF06E4BD837E, 0x892A2933A0FA1F63,
0x9F88FC67B6CCB461, 0x822926EA9DDA3AC8, 0xEAC8DDE5855425ED, 0x000618FE6DA37A80, // XQA1
0x1D9D32D2DC877C17, 0x5517CD8F71D5B02B, 0x395AFB8F6B60C117, 0x3AE31AC85F9098C8,
0x5F5341C198450848, 0xF8C609DBEA435C6A, 0xD832BC7EDC7BA5E4, 0x002AD98AA6968BF5, // XRA0
0xC466CAB0F73C2E5B, 0x7B1817148FB2CF9C, 0x873E87C099E470A0, 0xBB17AC6D17A7BAC1,
0xA146FDCD0F2E2A58, 0x88B311E9CEAB6201, 0x37604CF5C7951757, 0x0006804071C74BF9}; // XRA1
// Bob's generator values {XPB0, XQB0, XRB0 + XRB1*i} in GF(p503^2), expressed in Montgomery representation
static const uint64_t B_gen[6 * NWORDS64_FIELD] = {0xDF630FC5FB2468DB, 0xC30C5541C102040E, 0x3CDC9987B76511FC, 0xF54B5A09353D0CDD,
0x3ADBA8E00703C42F, 0x8253F9303DDC95D0, 0x62D30778763ABFD7, 0x001CD00FB581CD55, // XPB0
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, // XPB1
0x2E3457A12B429261, 0x311F94E89627DCF8, 0x5B71C98FD1DB73F6, 0x3671DB7DCFC21541,
0xB6D1484C9FE0CF4F, 0x19CD110717356E35, 0xF4F9FB00AC9919DF, 0x0035BC124D38A70B, // XQB0
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, // XQB1
0x2E08BB99413D2952, 0xD3021467CD088D72, 0x21017AF859752245, 0x26314ED8FFD9DE5C,
0x4AF43C73344B6686, 0xCFA1F91149DF0993, 0xF327A95365587A89, 0x000DBF54E03D3906, // XRB0
0x03E03FF342F5F304, 0x993D604D7B4B6E56, 0x80412F4D9280E71F, 0x0FFDC9EF990B3982,
0xE584E64C51604931, 0x1374F42AC8B0BBD7, 0x07D5BC37DFA41A5F, 0x00396CCFD61FD34C}; // XRB1
// Montgomery constant Montgomery_R2 = (2^512)^2 mod p503
static const uint64_t Montgomery_R2[NWORDS64_FIELD] = {0x5289A0CF641D011F, 0x9B88257189FED2B9, 0xA3B365D58DC8F17A, 0x5BC57AB6EFF168EC,
0x9E51998BD84D4423, 0xBF8999CBAC3B5695, 0x46E9127BCE14CDB6, 0x003F6CFCE8B81771};
// Value one in Montgomery representation
static const uint64_t Montgomery_one[NWORDS64_FIELD] = {0x00000000000003F9, 0x0000000000000000, 0x0000000000000000, 0xB400000000000000,
0x63CB1A6EA6DED2B4, 0x51689D8D667EB37D, 0x8ACD77C71AB24142, 0x0026FBAEC60F5953};
// Fixed parameters for isogeny tree computation
static const unsigned int strat_Alice[MAX_Alice - 1] = {
61, 32, 16, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1, 1,
4, 2, 1, 1, 2, 1, 1, 16, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1,
1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 29, 16, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1,
1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 13, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2,
1, 1, 2, 1, 1, 5, 4, 2, 1, 1, 2, 1, 1, 2, 1, 1, 1};
static const unsigned int strat_Bob[MAX_Bob - 1] = {
71, 38, 21, 13, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 5, 4, 2, 1, 1, 2, 1,
1, 2, 1, 1, 1, 9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, 17, 9,
5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 1, 2, 1,
1, 4, 2, 1, 1, 2, 1, 1, 33, 17, 9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1,
2, 1, 1, 8, 4, 2, 1, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 16, 8, 4, 2, 1, 1, 1, 2,
1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1};
// Setting up macro defines and including GF(p), GF(p^2), curve, isogeny and kex functions
#define fpcopy fpcopy503
#define fpzero fpzero503
#define fpadd fpadd503
#define fpsub fpsub503
#define fpneg fpneg503
#define fpdiv2 fpdiv2_503
#define fpcorrection fpcorrection503
#define fpmul_mont fpmul503_mont
#define fpsqr_mont fpsqr503_mont
#define fpinv_mont fpinv503_mont
#define fpinv_chain_mont fpinv503_chain_mont
#define fpinv_mont_bingcd fpinv503_mont_bingcd
#define fp2copy fp2copy503
#define fp2zero fp2zero503
#define fp2add fp2add503
#define fp2sub fp2sub503
#define fp2neg fp2neg503
#define fp2div2 fp2div2_503
#define fp2correction fp2correction503
#define fp2mul_mont fp2mul503_mont
#define fp2sqr_mont fp2sqr503_mont
#define fp2inv_mont fp2inv503_mont
#define fp2inv_mont_bingcd fp2inv503_mont_bingcd
#define fpequal_non_constant_time fpequal503_non_constant_time
#define mp_add_asm oqs_kem_sike_mp_add503_asm
#define mp_subaddx2_asm oqs_kem_sike_mp_subadd503x2_asm
#define mp_dblsubx2_asm oqs_kem_sike_mp_dblsub503x2_asm
#define crypto_kem_keypair OQS_KEM_sike_p503_keypair
#define crypto_kem_enc OQS_KEM_sike_p503_encaps
#define crypto_kem_dec OQS_KEM_sike_p503_decaps
#define random_mod_order_A oqs_kem_sidh_p503_random_mod_order_A
#define random_mod_order_B oqs_kem_sidh_p503_random_mod_order_B
#define EphemeralKeyGeneration_A oqs_kem_sidh_p503_EphemeralKeyGeneration_A
#define EphemeralKeyGeneration_B oqs_kem_sidh_p503_EphemeralKeyGeneration_B
#define EphemeralSecretAgreement_A oqs_kem_sidh_p503_EphemeralSecretAgreement_A
#define EphemeralSecretAgreement_B oqs_kem_sidh_p503_EphemeralSecretAgreement_B
#ifdef USE_SIKEP503_ASM
#define USE_SIKE_ASM
#endif
#if defined(X86_64)
#include "AMD64/fp_x64.c"
#elif defined(ARM64)
#include "ARM64/fp_arm64.c"
#else
#include "generic/fp_generic.c"
#endif
#include "../fpx.c"
#include "../ec_isogeny.c"
#include "../sidh.c"
#include "../sike.c"
/********************************************************************************************
* SIDH: an efficient supersingular isogeny cryptography library
*
* Abstract: supersingular isogeny parameters and generation of functions for P503
*********************************************************************************************/
#include <oqs/rand.h>
#include "../oqs_namespace_sike.h"
#include "P503_api.h"
#include "P503_internal.h"
// defines moved from P503_api.h
#define CRYPTO_SECRETKEYBYTES 434 // MSG_BYTES + SECRETKEY_B_BYTES + CRYPTO_PUBLICKEYBYTES bytes
#define CRYPTO_PUBLICKEYBYTES 378
#define CRYPTO_BYTES 24
#define CRYPTO_CIPHERTEXTBYTES 402 // CRYPTO_PUBLICKEYBYTES + MSG_BYTES bytes
#define SIDH_SECRETKEYBYTES_A 32
#define SIDH_SECRETKEYBYTES_B 32
#define SIDH_PUBLICKEYBYTES 378
#define SIDH_BYTES 126
// Encoding of field elements, elements over Z_order, elements over GF(p^2) and elliptic curve points:
// --------------------------------------------------------------------------------------------------
// Elements over GF(p) and Z_order are encoded with the least significant octet (and digit) located at the leftmost position (i.e., little endian format).
// Elements (a+b*i) over GF(p^2), where a and b are defined over GF(p), are encoded as {a, b}, with a in the least significant position.
// Elliptic curve points P = (x,y) are encoded as {x, y}, with x in the least significant position.
// Internally, the number of digits used to represent all these elements is obtained by approximating the number of bits to the immediately greater multiple of 32.
// For example, a 503-bit field element is represented with Ceil(503 / 64) = 8 64-bit digits or Ceil(503 / 32) = 16 32-bit digits.
//
// Curve isogeny system "SIDHp503". Base curve: Montgomery curve By^2 = Cx^3 + Ax^2 + Cx defined over GF(p503^2), where A=6, B=1, C=1 and p503 = 2^250*3^159-1
//
const uint64_t p503[NWORDS64_FIELD] = {0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xABFFFFFFFFFFFFFF,
0x13085BDA2211E7A0, 0x1B9BF6C87B7E7DAF, 0x6045C6BDDA77A4D0, 0x004066F541811E1E
};
const uint64_t p503p1[NWORDS64_FIELD] = {0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xAC00000000000000,
0x13085BDA2211E7A0, 0x1B9BF6C87B7E7DAF, 0x6045C6BDDA77A4D0, 0x004066F541811E1E
};
const uint64_t p503x2[NWORDS64_FIELD] = {0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x57FFFFFFFFFFFFFF,
0x2610B7B44423CF41, 0x3737ED90F6FCFB5E, 0xC08B8D7BB4EF49A0, 0x0080CDEA83023C3C
};
// Order of Alice's subgroup
static const uint64_t Alice_order[NWORDS64_ORDER] = {0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0400000000000000};
// Order of Bob's subgroup
static const uint64_t Bob_order[NWORDS64_ORDER] = {0xC216F6888479E82B, 0xE6FDB21EDF9F6BC4, 0x1171AF769DE93406, 0x1019BD5060478798};
// Alice's generator values {XPA0 + XPA1*i, XQA0 + XQA1*i, XRA0 + XRA1*i} in GF(p503^2), expressed in Montgomery representation
static const uint64_t A_gen[6 * NWORDS64_FIELD] = {0x5D083011589AD893, 0xADFD8D2CB67D0637, 0x330C9AC34FFB6361, 0xF0D47489A2E805A2,
0x27E2789259C6B8DC, 0x63866A2C121931B9, 0x8D4C65A7137DCF44, 0x003A183AE5967B3F, // XPA0
0x7E3541B8C96D1519, 0xD3ADAEEC0D61A26C, 0xC0A2219CE7703DD9, 0xFF3E46658FCDBC52,
0xD5B38DEAE6E196FF, 0x1AAC826364956D58, 0xEC9F4875B9A5F27A, 0x001B0B475AB99843, // XPA1
0x4D83695107D03BAD, 0x221F3299005E2FCF, 0x78E6AE22F30DECF2, 0x6D982DB5111253E4,
0x504C80A8AB4526A8, 0xEFD0C3AA210BB024, 0xCB77483501DC6FCF, 0x001052544A96BDF3, // XQA0
0x0D74FE3402BCAE47, 0xDF5B8CDA832D8AED, 0xB86BCF06E4BD837E, 0x892A2933A0FA1F63,
0x9F88FC67B6CCB461, 0x822926EA9DDA3AC8, 0xEAC8DDE5855425ED, 0x000618FE6DA37A80, // XQA1
0x1D9D32D2DC877C17, 0x5517CD8F71D5B02B, 0x395AFB8F6B60C117, 0x3AE31AC85F9098C8,
0x5F5341C198450848, 0xF8C609DBEA435C6A, 0xD832BC7EDC7BA5E4, 0x002AD98AA6968BF5, // XRA0
0xC466CAB0F73C2E5B, 0x7B1817148FB2CF9C, 0x873E87C099E470A0, 0xBB17AC6D17A7BAC1,
0xA146FDCD0F2E2A58, 0x88B311E9CEAB6201, 0x37604CF5C7951757, 0x0006804071C74BF9
}; // XRA1
// Bob's generator values {XPB0, XQB0, XRB0 + XRB1*i} in GF(p503^2), expressed in Montgomery representation
static const uint64_t B_gen[6 * NWORDS64_FIELD] = {0xDF630FC5FB2468DB, 0xC30C5541C102040E, 0x3CDC9987B76511FC, 0xF54B5A09353D0CDD,
0x3ADBA8E00703C42F, 0x8253F9303DDC95D0, 0x62D30778763ABFD7, 0x001CD00FB581CD55, // XPB0
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, // XPB1
0x2E3457A12B429261, 0x311F94E89627DCF8, 0x5B71C98FD1DB73F6, 0x3671DB7DCFC21541,
0xB6D1484C9FE0CF4F, 0x19CD110717356E35, 0xF4F9FB00AC9919DF, 0x0035BC124D38A70B, // XQB0
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, // XQB1
0x2E08BB99413D2952, 0xD3021467CD088D72, 0x21017AF859752245, 0x26314ED8FFD9DE5C,
0x4AF43C73344B6686, 0xCFA1F91149DF0993, 0xF327A95365587A89, 0x000DBF54E03D3906, // XRB0
0x03E03FF342F5F304, 0x993D604D7B4B6E56, 0x80412F4D9280E71F, 0x0FFDC9EF990B3982,
0xE584E64C51604931, 0x1374F42AC8B0BBD7, 0x07D5BC37DFA41A5F, 0x00396CCFD61FD34C
}; // XRB1
// Montgomery constant Montgomery_R2 = (2^512)^2 mod p503
static const uint64_t Montgomery_R2[NWORDS64_FIELD] = {0x5289A0CF641D011F, 0x9B88257189FED2B9, 0xA3B365D58DC8F17A, 0x5BC57AB6EFF168EC,
0x9E51998BD84D4423, 0xBF8999CBAC3B5695, 0x46E9127BCE14CDB6, 0x003F6CFCE8B81771
};
// Value one in Montgomery representation
static const uint64_t Montgomery_one[NWORDS64_FIELD] = {0x00000000000003F9, 0x0000000000000000, 0x0000000000000000, 0xB400000000000000,
0x63CB1A6EA6DED2B4, 0x51689D8D667EB37D, 0x8ACD77C71AB24142, 0x0026FBAEC60F5953
};
// Fixed parameters for isogeny tree computation
static const unsigned int strat_Alice[MAX_Alice - 1] = {
61, 32, 16, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1, 1,
4, 2, 1, 1, 2, 1, 1, 16, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1,
1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 29, 16, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1,
1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 13, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2,
1, 1, 2, 1, 1, 5, 4, 2, 1, 1, 2, 1, 1, 2, 1, 1, 1
};
static const unsigned int strat_Bob[MAX_Bob - 1] = {
71, 38, 21, 13, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 5, 4, 2, 1, 1, 2, 1,
1, 2, 1, 1, 1, 9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, 17, 9,
5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 1, 2, 1,
1, 4, 2, 1, 1, 2, 1, 1, 33, 17, 9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1,
2, 1, 1, 8, 4, 2, 1, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 16, 8, 4, 2, 1, 1, 1, 2,
1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1
};
// Setting up macro defines and including GF(p), GF(p^2), curve, isogeny and kex functions
#define fpcopy fpcopy503
#define fpzero fpzero503
#define fpadd fpadd503
#define fpsub fpsub503
#define fpneg fpneg503
#define fpdiv2 fpdiv2_503
#define fpcorrection fpcorrection503
#define fpmul_mont fpmul503_mont
#define fpsqr_mont fpsqr503_mont
#define fpinv_mont fpinv503_mont
#define fpinv_chain_mont fpinv503_chain_mont
#define fpinv_mont_bingcd fpinv503_mont_bingcd
#define fp2copy fp2copy503
#define fp2zero fp2zero503
#define fp2add fp2add503
#define fp2sub fp2sub503
#define fp2neg fp2neg503
#define fp2div2 fp2div2_503
#define fp2correction fp2correction503
#define fp2mul_mont fp2mul503_mont
#define fp2sqr_mont fp2sqr503_mont
#define fp2inv_mont fp2inv503_mont
#define fp2inv_mont_bingcd fp2inv503_mont_bingcd
#define fpequal_non_constant_time fpequal503_non_constant_time
#define mp_add_asm oqs_kem_sike_mp_add503_asm
#define mp_subaddx2_asm oqs_kem_sike_mp_subadd503x2_asm
#define mp_dblsubx2_asm oqs_kem_sike_mp_dblsub503x2_asm
#define crypto_kem_keypair OQS_KEM_sike_p503_keypair
#define crypto_kem_enc OQS_KEM_sike_p503_encaps
#define crypto_kem_dec OQS_KEM_sike_p503_decaps
#define random_mod_order_A oqs_kem_sidh_p503_random_mod_order_A
#define random_mod_order_B oqs_kem_sidh_p503_random_mod_order_B
#define EphemeralKeyGeneration_A oqs_kem_sidh_p503_EphemeralKeyGeneration_A
#define EphemeralKeyGeneration_B oqs_kem_sidh_p503_EphemeralKeyGeneration_B
#define EphemeralSecretAgreement_A oqs_kem_sidh_p503_EphemeralSecretAgreement_A
#define EphemeralSecretAgreement_B oqs_kem_sidh_p503_EphemeralSecretAgreement_B
#ifdef USE_SIKEP503_ASM
#define USE_SIKE_ASM
#endif
#if defined(X86_64)
#include "AMD64/fp_x64.c"
#elif defined(ARM64)
#include "ARM64/fp_arm64.c"
#else
#include "generic/fp_generic.c"
#endif
#include "../fpx.c"
#include "../ec_isogeny.c"
#include "../sidh.c"
#include "../sike.c"

View File

@ -33,11 +33,14 @@
//
static const uint64_t p503[NWORDS64_FIELD] = {0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xABFFFFFFFFFFFFFF,
0x13085BDA2211E7A0, 0x1B9BF6C87B7E7DAF, 0x6045C6BDDA77A4D0, 0x004066F541811E1E};
0x13085BDA2211E7A0, 0x1B9BF6C87B7E7DAF, 0x6045C6BDDA77A4D0, 0x004066F541811E1E
};
static const uint64_t p503p1[NWORDS64_FIELD] = {0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xAC00000000000000,
0x13085BDA2211E7A0, 0x1B9BF6C87B7E7DAF, 0x6045C6BDDA77A4D0, 0x004066F541811E1E};
0x13085BDA2211E7A0, 0x1B9BF6C87B7E7DAF, 0x6045C6BDDA77A4D0, 0x004066F541811E1E
};
static const uint64_t p503x2[NWORDS64_FIELD] = {0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x57FFFFFFFFFFFFFF,
0x2610B7B44423CF41, 0x3737ED90F6FCFB5E, 0xC08B8D7BB4EF49A0, 0x0080CDEA83023C3C};
0x2610B7B44423CF41, 0x3737ED90F6FCFB5E, 0xC08B8D7BB4EF49A0, 0x0080CDEA83023C3C
};
// Order of Alice's subgroup
static const uint64_t Alice_order[NWORDS64_ORDER] = {0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0400000000000000};
// Order of Bob's subgroup
@ -55,7 +58,8 @@ static const uint64_t A_gen[6 * NWORDS64_FIELD] = {0x3353B596D45A95A6, 0xDF7E0A9
0x1482EA2C7A8F5FA0, 0xB42C8B9C007E5FE5, 0xCFCFF2625C69E7FD, 0x8334C3F384C268F5,
0xD71E78E25FA4DB2F, 0x64BECFBE41708879, 0x103FF021EF7BF9, 0x2695BB8221E83B, // XRA0
0xA08787E922A1030, 0x8D34581F64BCE547, 0x2FA5BED41306271A, 0xEC24812ABD206DCF,
0x978FA888C3CC6366, 0x2BFF991CDB7CE058, 0xA0BCCC1A447CF056, 0x2425429A072D82}; // XRA1
0x978FA888C3CC6366, 0x2BFF991CDB7CE058, 0xA0BCCC1A447CF056, 0x2425429A072D82
}; // XRA1
/* Basis for Bob on A = 6, expressed in Montgomery representation */
static const uint64_t B_gen[6 * NWORDS64_FIELD] = {0xB810321963CF561F, 0xACA612873FBC647F, 0xE5C29CB78215B634, 0xB277ACABE764F907,
@ -68,13 +72,15 @@ static const uint64_t B_gen[6 * NWORDS64_FIELD] = {0xB810321963CF561F, 0xACA6128
0x45937210137F28D6, 0xE76DD3A731B45FB4, 0xD1C1A7F7030546EC, 0x1C3D5057DFF16D, // XQB1
0x6E3DEF7C8A5A47D2, 0x12D9AF90F92FC868, 0xCE33D50FC931894B, 0x2927354E05ED037C,
0x4864AD1D8B6E4E56, 0x2C6BB7E4CD4284DD, 0x50A30A93843DDC28, 0x38195667C39958, // XRB0
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; // XRB1
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
}; // XRB1
/* The x-coordinate of lB^(eB-1)*QB, expressed in Montgomery representation */
static const uint64_t XQB3[2 * NWORDS64_FIELD] = {0xEE99D64B76EDCAB8, 0x24081A5326BA0FF9, 0x2BCFD2861E3D63FA, 0xA0964C6F4D7EB493,
0x171019237F558103, 0xA19A27B706871B49, 0xECC7384313612D3C, 0xA3EC9B9537811,
0xA7CD1086A7F15A87, 0x21A78B0FFA3920DC, 0xBDBDD8A49264C6D1, 0x925A193B79F45BB9,
0xD3E14C9F15E21C4E, 0x6A218D16356EE2CE, 0x9D0D5E4AAA37DE6D, 0x17C49B586430A4};
0xD3E14C9F15E21C4E, 0x6A218D16356EE2CE, 0x9D0D5E4AAA37DE6D, 0x17C49B586430A4
};
static const uint64_t A_basis_zero[8 * NWORDS64_FIELD] = {0x3353B596D45A9D99, 0xDF7E0A94A39B96C0, 0x715DC90A72A3223F, 0x8773F56E5AD9430F,
0x9943B35C469A0526, 0xB964613981C02523, 0x43F68F92C55B886, 0x18B5A8D224F483,
@ -91,7 +97,8 @@ static const uint64_t A_basis_zero[8 * NWORDS64_FIELD] = {0x3353B596D45A9D99, 0x
0x986343072253CB59, 0x675F6504D2978FEC, 0xA0A52D48BA2141EA, 0x623302893A18D8D1,
0x56B48005611F5B79, 0xE398D5F901FB591F, 0xE5A41D9AFCF35177, 0x391CDEF0EEFA35,
0xE9B1DB43D63D7EE9, 0x8BC7B3CEB5A89BAE, 0xC0DDDEFB4D9CDCD, 0xB9873A36C1B0B949,
0x97FCE091A32E2501, 0x838C61141A0FB449, 0xA4B61F965220A71F, 0x16978E2D5FBE08};
0x97FCE091A32E2501, 0x838C61141A0FB449, 0xA4B61F965220A71F, 0x16978E2D5FBE08
};
/* Basis for Bob on A = 0, expressed in Montgomery representation */
static const uint64_t B_basis_zero[8 * NWORDS64_FIELD] = {0x4256C520FB388820, 0x744FD7C3BAAF0A13, 0x4B6A2DDDB12CBCB8, 0xE46826E27F427DF8,
@ -105,7 +112,8 @@ static const uint64_t B_basis_zero[8 * NWORDS64_FIELD] = {0x4256C520FB388820, 0x
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x440192590061240E, 0x60C942451EC3E20D, 0x2195638E3B7632CA, 0xBA84AC322AA59D16,
0x3751CBF97048E02D, 0x6A583E4C816EAC44, 0x7A984D4F477762C1, 0x27B5AB2E503D63};
0x3751CBF97048E02D, 0x6A583E4C816EAC44, 0x7A984D4F477762C1, 0x27B5AB2E503D63
};
/* Full 3-torsion for Bob on A = 0, expressed in Montgomery representation */
static const uint64_t B_gen_3_tors[16 * NWORDS64_FIELD] = {0xAA6FCA1A7DB3B9C1, 0x8D12C496B3D530CE, 0x909089D6DB66CE9F, 0x26979B12182E911,
@ -133,16 +141,19 @@ static const uint64_t B_gen_3_tors[16 * NWORDS64_FIELD] = {0xAA6FCA1A7DB3B9C1, 0
0xDC6CDA78FBC6D660, 0xAB35FE4E0DB497, 0x4CD08BF7B90D948B, 0xDD38F40AED30B440,
0x5C9D9A2A66152FA5, 0x8143357E694594D8, 0x4331EA627E400226, 0x274E4E416D3346,
0xDC6CDA78FBC6D660, 0xAB35FE4E0DB497, 0x4CD08BF7B90D948B, 0xDD38F40AED30B440,
0x5C9D9A2A66152FA5, 0x8143357E694594D8, 0x4331EA627E400226, 0x274E4E416D3346};
0x5C9D9A2A66152FA5, 0x8143357E694594D8, 0x4331EA627E400226, 0x274E4E416D3346
};
/* Pre-computed pairing ReducedTatePairing(R0,S3,lB^eB) on A = 0 */
static const uint64_t g_R_S_im[NWORDS64_FIELD] = {0xF74CEB25BB76E955, 0x12040D29935D07FC, 0x95E7E9430F1EB1FD, 0x844B2637A6BF5A49,
0xEF53270066899336, 0xA235B168E9C24121, 0x813113E8A462D7E0, 0x2C1B13A2B9155C};
0xEF53270066899336, 0xA235B168E9C24121, 0x813113E8A462D7E0, 0x2C1B13A2B9155C
};
static const uint64_t Montgomery_R[NWORDS64_FIELD] = {0};
// Montgomery constant Montgomery_R2 = (2^512)^2 mod p503
static const uint64_t Montgomery_R2[NWORDS64_FIELD] = {0x5289A0CF641D011F, 0x9B88257189FED2B9, 0xA3B365D58DC8F17A, 0x5BC57AB6EFF168EC,
0x9E51998BD84D4423, 0xBF8999CBAC3B5695, 0x46E9127BCE14CDB6, 0x003F6CFCE8B81771};
0x9E51998BD84D4423, 0xBF8999CBAC3B5695, 0x46E9127BCE14CDB6, 0x003F6CFCE8B81771
};
// constant Montgomery_RB1 = (2^NBITS_ORDER)^2 mod Bob_order
static const uint64_t Montgomery_RB1[NWORDS64_FIELD] = {0xC2615CA3C5BAA99, 0x5A4FF3072AB6AA6A, 0xA6AFD4B039AD6AA2, 0x10DA06A26DD05CB};
@ -152,38 +163,44 @@ static const uint64_t Montgomery_RB2[NWORDS64_FIELD] = {0x49C8A87190C0697D, 0x2E
// Value one in Montgomery representation
static const uint64_t Montgomery_one[NWORDS64_FIELD] = {0x00000000000003F9, 0x0000000000000000, 0x0000000000000000, 0xB400000000000000,
0x63CB1A6EA6DED2B4, 0x51689D8D667EB37D, 0x8ACD77C71AB24142, 0x0026FBAEC60F5953};
0x63CB1A6EA6DED2B4, 0x51689D8D667EB37D, 0x8ACD77C71AB24142, 0x0026FBAEC60F5953
};
// 1/3 mod p
static const uint64_t threeinv[NWORDS64_FIELD] = {
0x55555555555556A8, 0x5555555555555555, 0x5555555555555555, 0x7555555555555555, 0x7CF1276D98503E1C, 0xCF0186C74B5465B9, 0xA3B114D6FC634CB0, 0x227636AD3027D0};
0x55555555555556A8, 0x5555555555555555, 0x5555555555555555, 0x7555555555555555, 0x7CF1276D98503E1C, 0xCF0186C74B5465B9, 0xA3B114D6FC634CB0, 0x227636AD3027D0
};
// Fixed parameters for isogeny tree computation
static const unsigned int strat_Alice[MAX_Alice - 1] = {
61, 32, 16, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1, 1,
4, 2, 1, 1, 2, 1, 1, 16, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1,
1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 29, 16, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1,
1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 13, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2,
1, 1, 2, 1, 1, 5, 4, 2, 1, 1, 2, 1, 1, 2, 1, 1, 1};
61, 32, 16, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1, 1,
4, 2, 1, 1, 2, 1, 1, 16, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1,
1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 29, 16, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1,
1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 13, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2,
1, 1, 2, 1, 1, 5, 4, 2, 1, 1, 2, 1, 1, 2, 1, 1, 1
};
static const unsigned int strat_Bob[MAX_Bob - 1] = {
71, 38, 21, 13, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 5, 4, 2, 1, 1, 2, 1,
1, 2, 1, 1, 1, 9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, 17, 9,
5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 1, 2, 1,
1, 4, 2, 1, 1, 2, 1, 1, 33, 17, 9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1,
2, 1, 1, 8, 4, 2, 1, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 16, 8, 4, 2, 1, 1, 1, 2,
1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1};
71, 38, 21, 13, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 5, 4, 2, 1, 1, 2, 1,
1, 2, 1, 1, 1, 9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, 17, 9,
5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 1, 2, 1,
1, 4, 2, 1, 1, 2, 1, 1, 33, 17, 9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1,
2, 1, 1, 8, 4, 2, 1, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 16, 8, 4, 2, 1, 1, 1, 2,
1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1
};
// Fixed traversal strategies for Pohlig-Hellman discrete logs
static const unsigned int ph2_path[PLEN_2] = { // w_2 = 5
0, 0, 1, 2, 3, 4, 4, 5, 5, 6, 7, 7, 8, 9, 10, 10, 11, 12, 13, 13, 14, 14, 15, 16,
17, 18, 18, 18, 19, 20, 20, 21, 22, 23, 24, 25, 25, 25, 25, 26, 27, 28, 29, 29,
30, 31, 32, 33, 34, 35, 35};
0, 0, 1, 2, 3, 4, 4, 5, 5, 6, 7, 7, 8, 9, 10, 10, 11, 12, 13, 13, 14, 14, 15, 16,
17, 18, 18, 18, 19, 20, 20, 21, 22, 23, 24, 25, 25, 25, 25, 26, 27, 28, 29, 29,
30, 31, 32, 33, 34, 35, 35
};
static const unsigned int ph3_path[PLEN_3] = { // w_3 = 6
0, 0, 1, 2, 3, 4, 5, 6, 6, 7, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 16, 16, 17,
18, 19, 20, 21};
0, 0, 1, 2, 3, 4, 5, 6, 6, 7, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 16, 16, 17,
18, 19, 20, 21
};
// Entangled bases related static tables and parameters
@ -195,145 +212,152 @@ static const unsigned int ph3_path[PLEN_3] = { // w_3 = 6
// A table of size 20 for values v = 1/(1+U*r^2)
static const uint64_t u_entang[2 * NWORDS64_FIELD] = {
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7F3, 0x0, 0x0, 0xBC00000000000000, 0xB48DD9032BABBDC8, 0x87354452517EE94B, 0xB55528D05AECDDB4, 0xD90684A9D9488};
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7F3, 0x0, 0x0, 0xBC00000000000000, 0xB48DD9032BABBDC8, 0x87354452517EE94B, 0xB55528D05AECDDB4, 0xD90684A9D9488
};
static const uint64_t u0_entang[2 * NWORDS64_FIELD] = {
0x3F9, 0x0, 0x0, 0xB400000000000000, 0x63CB1A6EA6DED2B4, 0x51689D8D667EB37D, 0x8ACD77C71AB24142, 0x26FBAEC60F5953, 0x3F9, 0x0, 0x0, 0xB400000000000000,
0x63CB1A6EA6DED2B4, 0x51689D8D667EB37D, 0x8ACD77C71AB24142, 0x26FBAEC60F5953};
0x3F9, 0x0, 0x0, 0xB400000000000000, 0x63CB1A6EA6DED2B4, 0x51689D8D667EB37D, 0x8ACD77C71AB24142, 0x26FBAEC60F5953, 0x3F9, 0x0, 0x0, 0xB400000000000000,
0x63CB1A6EA6DED2B4, 0x51689D8D667EB37D, 0x8ACD77C71AB24142, 0x26FBAEC60F5953
};
// Tables for quadratic residues and quadratic non residues v with 17 elements each.
static const uint64_t table_r_qr[TABLE_R_LEN][NWORDS64_FIELD] =
{{0xBEC, 0x0, 0x0, 0x7000000000000000, 0x1858F371D28A907D, 0xD89DE1DFB7FD9CC9, 0x4022A097759F1EF6, 0x348C1710ACEDDC},
{0x17D9, 0x0, 0x0, 0x3400000000000000, 0x1DA98B098303395A, 0x959FCCF6F47CBBE3, 0x1FFF7A7110C6991D, 0x28B138DFD8BD9A},
{0x23C6, 0x0, 0x0, 0xF800000000000000, 0x22FA22A1337BE236, 0x52A1B80E30FBDAFD, 0xFFDC544AABEE1344, 0x1CD65AAF048D57},
{0x2BB9, 0x0, 0x0, 0xB400000000000000, 0xD787FBA45F279FFF, 0xD9D6FC60827AC448, 0xB5317D1B06DAF0F8, 0x2A66C2F9A221E0},
{0x2FB3, 0x0, 0x0, 0xBC00000000000000, 0x284ABA38E3F48B13, 0xFA3A3256D7AFA17, 0xDFB92E2447158D6B, 0x10FB7C7E305D15},
{0x33AC, 0x0, 0x0, 0x7000000000000000, 0x8C15D4A78AD35DC8, 0x610C40B2D3F9AD94, 0x6A86A5EB61C7CEAD, 0x37F72B443FB669},
{0x3BA0, 0x0, 0x0, 0x8000000000000000, 0x2D9B51D0946D33F0, 0xCCA58E3CA9FA1931, 0xBF9607FDE23D0791, 0x5209E4D5C2CD3},
{0x3F99, 0x0, 0x0, 0x3400000000000000, 0x91666C3F3B4C06A5, 0x1E0E2BCA1078CCAE, 0x4A637FC4FCEF48D4, 0x2C1C4D136B8627},
{0x478C, 0x0, 0x0, 0xF000000000000000, 0x45F4454266F7C46D, 0xA543701C61F7B5FA, 0xFFB8A89557DC2688, 0x39ACB55E091AAF},
{0x4B86, 0x0, 0x0, 0xF800000000000000, 0x96B703D6EBC4AF81, 0xDB1016E14CF7EBC8, 0x2A40599E9816C2FA, 0x20416EE29755E5},
{0x5379, 0x0, 0x0, 0xB400000000000000, 0x4B44DCDA17706D4A, 0x62455B339E76D514, 0xDF95826EF303A0AF, 0x2DD1D72D34EA6D},
{0x5773, 0x0, 0x0, 0xBC00000000000000, 0x9C079B6E9C3D585E, 0x981201F889770AE2, 0xA1D3378333E3D21, 0x146690B1C325A3},
{0x5B6C, 0x0, 0x0, 0x7000000000000000, 0xFFD2B5DD431C2B13, 0xE97A9F85EFF5BE5F, 0x94EAAB3F4DF07E63, 0x3B623F77D27EF6},
{0x5F66, 0x0, 0x0, 0x7800000000000000, 0x50957471C7E91627, 0x1F47464ADAF5F42E, 0xBF725C488E2B1AD6, 0x21F6F8FC60BA2B},
{0x6360, 0x0, 0x0, 0x8000000000000000, 0xA15833064CB6013B, 0x5513ED0FC5F629FC, 0xE9FA0D51CE65B748, 0x88BB280EEF560},
{0x6759, 0x0, 0x0, 0x3400000000000000, 0x5234D74F394D3F0, 0xA67C8A9D2C74DD7A, 0x74C78518E917F88A, 0x2F876146FE4EB4},
{0x6B53, 0x0, 0x0, 0x3C00000000000000, 0x55E60C097861BF04, 0xDC49316217751348, 0x9F4F3622295294FC, 0x161C1ACB8C89E9}};
static const uint64_t table_r_qr[TABLE_R_LEN][NWORDS64_FIELD] = {
{0xBEC, 0x0, 0x0, 0x7000000000000000, 0x1858F371D28A907D, 0xD89DE1DFB7FD9CC9, 0x4022A097759F1EF6, 0x348C1710ACEDDC},
{0x17D9, 0x0, 0x0, 0x3400000000000000, 0x1DA98B098303395A, 0x959FCCF6F47CBBE3, 0x1FFF7A7110C6991D, 0x28B138DFD8BD9A},
{0x23C6, 0x0, 0x0, 0xF800000000000000, 0x22FA22A1337BE236, 0x52A1B80E30FBDAFD, 0xFFDC544AABEE1344, 0x1CD65AAF048D57},
{0x2BB9, 0x0, 0x0, 0xB400000000000000, 0xD787FBA45F279FFF, 0xD9D6FC60827AC448, 0xB5317D1B06DAF0F8, 0x2A66C2F9A221E0},
{0x2FB3, 0x0, 0x0, 0xBC00000000000000, 0x284ABA38E3F48B13, 0xFA3A3256D7AFA17, 0xDFB92E2447158D6B, 0x10FB7C7E305D15},
{0x33AC, 0x0, 0x0, 0x7000000000000000, 0x8C15D4A78AD35DC8, 0x610C40B2D3F9AD94, 0x6A86A5EB61C7CEAD, 0x37F72B443FB669},
{0x3BA0, 0x0, 0x0, 0x8000000000000000, 0x2D9B51D0946D33F0, 0xCCA58E3CA9FA1931, 0xBF9607FDE23D0791, 0x5209E4D5C2CD3},
{0x3F99, 0x0, 0x0, 0x3400000000000000, 0x91666C3F3B4C06A5, 0x1E0E2BCA1078CCAE, 0x4A637FC4FCEF48D4, 0x2C1C4D136B8627},
{0x478C, 0x0, 0x0, 0xF000000000000000, 0x45F4454266F7C46D, 0xA543701C61F7B5FA, 0xFFB8A89557DC2688, 0x39ACB55E091AAF},
{0x4B86, 0x0, 0x0, 0xF800000000000000, 0x96B703D6EBC4AF81, 0xDB1016E14CF7EBC8, 0x2A40599E9816C2FA, 0x20416EE29755E5},
{0x5379, 0x0, 0x0, 0xB400000000000000, 0x4B44DCDA17706D4A, 0x62455B339E76D514, 0xDF95826EF303A0AF, 0x2DD1D72D34EA6D},
{0x5773, 0x0, 0x0, 0xBC00000000000000, 0x9C079B6E9C3D585E, 0x981201F889770AE2, 0xA1D3378333E3D21, 0x146690B1C325A3},
{0x5B6C, 0x0, 0x0, 0x7000000000000000, 0xFFD2B5DD431C2B13, 0xE97A9F85EFF5BE5F, 0x94EAAB3F4DF07E63, 0x3B623F77D27EF6},
{0x5F66, 0x0, 0x0, 0x7800000000000000, 0x50957471C7E91627, 0x1F47464ADAF5F42E, 0xBF725C488E2B1AD6, 0x21F6F8FC60BA2B},
{0x6360, 0x0, 0x0, 0x8000000000000000, 0xA15833064CB6013B, 0x5513ED0FC5F629FC, 0xE9FA0D51CE65B748, 0x88BB280EEF560},
{0x6759, 0x0, 0x0, 0x3400000000000000, 0x5234D74F394D3F0, 0xA67C8A9D2C74DD7A, 0x74C78518E917F88A, 0x2F876146FE4EB4},
{0x6B53, 0x0, 0x0, 0x3C00000000000000, 0x55E60C097861BF04, 0xDC49316217751348, 0x9F4F3622295294FC, 0x161C1ACB8C89E9}
};
static const uint64_t table_r_qnr[TABLE_R_LEN][NWORDS64_FIELD] =
{{0x3F9, 0x0, 0x0, 0xB400000000000000, 0x63CB1A6EA6DED2B4, 0x51689D8D667EB37D, 0x8ACD77C71AB24142, 0x26FBAEC60F5953},
{0x7F3, 0x0, 0x0, 0xBC00000000000000, 0xB48DD9032BABBDC8, 0x87354452517EE94B, 0xB55528D05AECDDB4, 0xD90684A9D9488},
{0xFE6, 0x0, 0x0, 0x7800000000000000, 0x691BB20657577B91, 0xE6A88A4A2FDD297, 0x6AAA51A0B5D9BB69, 0x1B20D0953B2911},
{0x13E0, 0x0, 0x0, 0x8000000000000000, 0xB9DE709ADC2466A5, 0x44372F698DFE0865, 0x953202A9F61457DB, 0x1B58A19C96446},
{0x1BD3, 0x0, 0x0, 0x3C00000000000000, 0x6E6C499E07D0246E, 0xCB6C73BBDF7CF1B1, 0x4A872B7A5101358F, 0xF45F26466F8CF},
{0x1FCC, 0x0, 0x0, 0xF000000000000000, 0xD237640CAEAEF722, 0x1CD5114945FBA52E, 0xD554A3416BB376D2, 0x3641A12A765222},
{0x27C0, 0x0, 0x0, 0x0, 0x73BCE135B848CD4B, 0x886E5ED31BFC10CB, 0x2A640553EC28AFB6, 0x36B143392C88D},
{0x37A6, 0x0, 0x0, 0x7800000000000000, 0xDCD8933C0FA048DC, 0x96D8E777BEF9E362, 0x950E56F4A2026B1F, 0x1E8BE4C8CDF19E},
{0x4393, 0x0, 0x0, 0x3C00000000000000, 0xE2292AD3C018F1B9, 0x53DAD28EFB79027C, 0x74EB30CE3D29E546, 0x12B10697F9C15C},
{0x4F80, 0x0, 0x0, 0x0, 0xE779C26B70919A96, 0x10DCBDA637F82196, 0x54C80AA7D8515F6D, 0x6D6286725911A},
{0x6F4C, 0x0, 0x0, 0xF000000000000000, 0xB9B126781F4091B8, 0x2DB1CEEF7DF3C6C5, 0x2A1CADE94404D63F, 0x3D17C9919BE33D},
{0x7346, 0x0, 0x0, 0xF800000000000000, 0xA73E50CA40D7CCC, 0x637E75B468F3FC94, 0x54A45EF2843F72B1, 0x23AC83162A1E72},
{0x7740, 0x0, 0x0, 0x0, 0x5B36A3A128DA67E1, 0x994B1C7953F43262, 0x7F2C0FFBC47A0F23, 0xA413C9AB859A7},
{0x7B39, 0x0, 0x0, 0xB400000000000000, 0xBF01BE0FCFB93A95, 0xEAB3BA06BA72E5DF, 0x9F987C2DF2C5065, 0x313CEB60C7B2FB},
{0x8B20, 0x0, 0x0, 0x8000000000000000, 0x1515143C04FECE86, 0xDD824BE2E1F23AC8, 0x145E12A5BA8E66FE, 0xBF6C6B481BDEE},
{0x8F19, 0x0, 0x0, 0x3400000000000000, 0x78E02EAAABDDA13B, 0x2EEAE9704870EE45, 0x9F2B8A6CD540A841, 0x32F2757A911741},
{0x9F00, 0x0, 0x0, 0x0, 0xCEF384D6E123352C, 0x21B97B4C6FF0432D, 0xA990154FB0A2BEDA, 0xDAC50CE4B2234}};
static const uint64_t table_r_qnr[TABLE_R_LEN][NWORDS64_FIELD] = {
{0x3F9, 0x0, 0x0, 0xB400000000000000, 0x63CB1A6EA6DED2B4, 0x51689D8D667EB37D, 0x8ACD77C71AB24142, 0x26FBAEC60F5953},
{0x7F3, 0x0, 0x0, 0xBC00000000000000, 0xB48DD9032BABBDC8, 0x87354452517EE94B, 0xB55528D05AECDDB4, 0xD90684A9D9488},
{0xFE6, 0x0, 0x0, 0x7800000000000000, 0x691BB20657577B91, 0xE6A88A4A2FDD297, 0x6AAA51A0B5D9BB69, 0x1B20D0953B2911},
{0x13E0, 0x0, 0x0, 0x8000000000000000, 0xB9DE709ADC2466A5, 0x44372F698DFE0865, 0x953202A9F61457DB, 0x1B58A19C96446},
{0x1BD3, 0x0, 0x0, 0x3C00000000000000, 0x6E6C499E07D0246E, 0xCB6C73BBDF7CF1B1, 0x4A872B7A5101358F, 0xF45F26466F8CF},
{0x1FCC, 0x0, 0x0, 0xF000000000000000, 0xD237640CAEAEF722, 0x1CD5114945FBA52E, 0xD554A3416BB376D2, 0x3641A12A765222},
{0x27C0, 0x0, 0x0, 0x0, 0x73BCE135B848CD4B, 0x886E5ED31BFC10CB, 0x2A640553EC28AFB6, 0x36B143392C88D},
{0x37A6, 0x0, 0x0, 0x7800000000000000, 0xDCD8933C0FA048DC, 0x96D8E777BEF9E362, 0x950E56F4A2026B1F, 0x1E8BE4C8CDF19E},
{0x4393, 0x0, 0x0, 0x3C00000000000000, 0xE2292AD3C018F1B9, 0x53DAD28EFB79027C, 0x74EB30CE3D29E546, 0x12B10697F9C15C},
{0x4F80, 0x0, 0x0, 0x0, 0xE779C26B70919A96, 0x10DCBDA637F82196, 0x54C80AA7D8515F6D, 0x6D6286725911A},
{0x6F4C, 0x0, 0x0, 0xF000000000000000, 0xB9B126781F4091B8, 0x2DB1CEEF7DF3C6C5, 0x2A1CADE94404D63F, 0x3D17C9919BE33D},
{0x7346, 0x0, 0x0, 0xF800000000000000, 0xA73E50CA40D7CCC, 0x637E75B468F3FC94, 0x54A45EF2843F72B1, 0x23AC83162A1E72},
{0x7740, 0x0, 0x0, 0x0, 0x5B36A3A128DA67E1, 0x994B1C7953F43262, 0x7F2C0FFBC47A0F23, 0xA413C9AB859A7},
{0x7B39, 0x0, 0x0, 0xB400000000000000, 0xBF01BE0FCFB93A95, 0xEAB3BA06BA72E5DF, 0x9F987C2DF2C5065, 0x313CEB60C7B2FB},
{0x8B20, 0x0, 0x0, 0x8000000000000000, 0x1515143C04FECE86, 0xDD824BE2E1F23AC8, 0x145E12A5BA8E66FE, 0xBF6C6B481BDEE},
{0x8F19, 0x0, 0x0, 0x3400000000000000, 0x78E02EAAABDDA13B, 0x2EEAE9704870EE45, 0x9F2B8A6CD540A841, 0x32F2757A911741},
{0x9F00, 0x0, 0x0, 0x0, 0xCEF384D6E123352C, 0x21B97B4C6FF0432D, 0xA990154FB0A2BEDA, 0xDAC50CE4B2234}
};
static const uint64_t table_v_qr[TABLE_V_LEN][NWORDS64_FIELD] =
{{0xD640973CA6FDA33, 0x30D640973CA6FDA3, 0xA30D640973CA6FDA, 0x9630D640973CA6FD, 0xB9B362A86413EF5, 0x291A8D3DCCB3503C, 0x28AA7266E86C4410, 0x3E57A5066529FA},
{0xEF755DBC422A858, 0x90EF755DBC422A89, 0x890EF755DBC422A8, 0x8890EF755DBC422A, 0x85ACA658F4ABDC07, 0xD196BC04A493216, 0xE8EBEE1D04CCCD7F, 0x2513A427F72A8B},
{0xEADE47323668C519, 0x19083ECD7DC0E6AB, 0xABEADE47323668C5, 0xF919083ECD7DC0E6, 0xB14832196A6135B, 0x65C238AE07A19315, 0x33892F2EF24CBA75, 0xEB6BD00093E7D},
{0xF17BF9E0B28890E7, 0xF5AE5634A1BF1FA5, 0xA5F17BF9E0B28890, 0x5CF5AE5634A1BF1F, 0x25C93809E47AEFCD, 0x36BB725E0DF4FAB5, 0xE60CED675C5D80CD, 0x23712156F96CCD},
{0x1C678311555200F, 0x4D5264E0DACE9D42, 0x12A66D44591361B5, 0x5631C420E42BD0E8, 0xC7CA70C8F9037B, 0x345253296A40C7FC, 0xF44CE094886CA2C1, 0x3DAD6A1ADCE6F6},
{0xE067F0F08021B5E6, 0x11DC29B589407C3A, 0x32AEDABFA1BC2B45, 0x4481E32F9C45CD24, 0x1AA9DD8D9554F1DC, 0xB6F1C1F604160937, 0x11DEFDB2CC29708D, 0x37004EEAE4323C},
{0xE36097357D9260F6, 0x439C0A04D12BD483, 0x66E8351E74487091, 0x1421CC574D451882, 0xAEB61FAD8599E2CA, 0x48EF54E42C5C665F, 0xED1A8E11AC6A738D, 0x16259CACCC3BDD},
{0xEB10F6F4BA05720, 0x167E877244911B53, 0xB87DC936138596AE, 0x680CD578F4AED4BA, 0x1694318AE2679DB1, 0x1CEEBA16962876FF, 0x73CAE996B2A0D8BA, 0x323A5E254D4A2D},
{0xAF443325C49FC9C7, 0xF3368ED80D8E2E2D, 0x5C49FC9C7474942E, 0xCCD8E2E2DAF44332, 0x471B92FFA7F05FFB, 0x8C55AC5DD5163AAD, 0xD41A2EDB81C0F26E, 0x12B9411FE82E2A},
{0xD3467582CC3CFFCC, 0x629F4CF0C00C0C9A, 0x2CC3CFFCFCD94B2E, 0xFC00C0C9AD346758, 0x3FB8C3F63F740571, 0x2ECB1038CC7F3A82, 0xF9707F59B63157EB, 0x115F359929F1C8},
{0x3218F78BA3CBAE8D, 0x19C8ECF809D7722F, 0x7097E87F9E319229, 0x1FCB0DEE58D468E5, 0xD0E9B55BF73DCF1F, 0x1EFE4FCE69BC0416, 0xEF0693CEC4EE816A, 0xBD45626E7A975},
{0xDB0929A1BD138997, 0xF4B72083018B3DAF, 0x576F0781228D05BB, 0x59E79B4EB78D8111, 0xDA7D2741F2CC8972, 0xDF9C5CCEC9E387F5, 0x1A7CC1B8C08AB119, 0x3AFC9BC0E8ABC4},
{0xEEAAAB192225A66F, 0x3D36F4A6197D1682, 0x95351AD9A4013A92, 0x737FCA70517EACFE, 0x546BE45BE532FB91, 0xCC1BAF4DF9C83B85, 0xB7F98958BFF6909C, 0x3A327C901E0790},
{0x77FF3DD1F9D16F4B, 0x6565F407321E6DD8, 0xB8A6CD6DB5D70AF0, 0x6D5E2690BF53E87D, 0xDCA29E4346D90AC4, 0x1C4B31AB442130F8, 0xAA4B89D4E4CCD33D, 0x16F0F5CF7D95E7},
{0x8CAE1CD478CAE1CD, 0xAE1CD478CAE1CD47, 0x1CD478CAE1CD478C, 0x1878CAE1CD478CAE, 0xFAD9099BBD3A4347, 0x67F1D575139CB5BF, 0x38293A715DDCB486, 0x123FF210860EF6},
{0xA3C6570E6A3C656E, 0xC6570E6A3C6570E6, 0x570E6A3C6570E6A3, 0x266A3C6570E6A3C6, 0x28B12AECF9AF8B71, 0xDB47D42F34B82DE3, 0x9556758ADED2F1DF, 0x3AD3BE4F8540E2},
{0xCA6337B265BAB821, 0xDFD5196D5A6AC701, 0x5931D9A74BA1FF5A, 0xD0C5E74C37D3F402, 0x4D621242F79E2216, 0x57F1976F8DF43182, 0xF052D77BBE57890B, 0x26C6CA2E21363A},
{0xB4DB046E7F5DEAF1, 0x6C97A33321B84377, 0x39D110888DF1A1F9, 0x3F0E8712AF7E5A0E, 0x318610A741127CA6, 0x8FAE99D54C14A492, 0xB8E11ABEDF29D523, 0x3610D24823BB34},
{0xBCEE07864886985B, 0x893DFD453F69DBD8, 0x846663A2582C0992, 0x90BD04A8B4E03846, 0xAC8F553BEBE4AAA3, 0x21D7DE00A60E1DBA, 0xD25E1FED110FEECB, 0x2A3CA66830CF45},
{0x28AEC74774664D80, 0xEF2BB2B32771F6BB, 0x973B002353CD00B8, 0x42E8DC31DFA1491E, 0x913BAEE3CA3D9E30, 0xABF6D1605464DDAE, 0xF3BBF0EC6297B06D, 0x1F94C96F693152},
{0x13C45267DD75029B, 0x2A5B4B4FF8E045B9, 0x3A2CEEEDFA82F7D8, 0x9E84B2F89B9CECA, 0x6F9D9229FB56184A, 0xE7CFAA7031AA43EF, 0xAB559E585413397D, 0x3410E7C5B657C2},
{0xE59C162702DD0330, 0x117686788B4FC859, 0x9130D016E8C6193E, 0x95ACF6377DD58B43, 0x886E99BF17505709, 0x5785149D522C7B5C, 0x35A0C131A77598A4, 0x3CE98183E3A406},
{0xF66188E646E44D38, 0x1DDB967838C24787, 0xF0DDC924163B32D9, 0xF3085EC466F80420, 0xCDC2841D90A1671D, 0x42C7CECE348BFCC8, 0x56B81B6CB2CA11DB, 0x3514702E4A9A0A},
{0x5F325943F0BC0122, 0x19AF0969616185E4, 0x395F6F8BF027BB07, 0x3059A95AA6306371, 0x4C8AC22B51821D99, 0x8CA5493A42F7F073, 0x3159D0CAF4E03BA1, 0xBA85326656B98},
{0x355770484B8F9E78, 0x3CE74F9FB70AE2AF, 0x29C66659490DA55A, 0x4A4908AB5BFCCAB2, 0x28E847CF76744D1B, 0xD73C1DA7E9743E83, 0xBC0814A45DE92E, 0x231BAF63ED339C},
{0x8CA1F537B87311CF, 0x4C08EDED850327E5, 0x5A0D0300159AA110, 0xAA2A2BCDD5424BAF, 0xD5DE3F3F3DB4665A, 0xB414A9EB85AEED8A, 0xF42B8C9A1B8CC578, 0xFA3EDA9B597BB},
{0xA67D8C524B3E4E75, 0x86499A8DBF7A9491, 0x72F4B7F3EA4620AD, 0x4817A8E2631DE824, 0xBB8AFA3312167C4A, 0xFC6430A72CDFEFB7, 0x8D35B46A38FE2241, 0x175BFA3B8577D},
{0xCB088DAD679EF165, 0xB4C8822258637092, 0xB2C43661C46CF323, 0xB9880541F96B5BFA, 0x107BCA3032B41FAD, 0x269816DB16A086AB, 0xB5B0180593043903, 0x38FD7D2B147838},
{0x475B7B82B2D288B0, 0x22C1F565B3292571, 0x59C43DCA0D6C8F10, 0xE1F36E62396C705C, 0xF83EB8755AE3C245, 0x8AD232E4B45B2625, 0x877CD62B7C9672AD, 0x89DA6104B553C},
{0x934EEBD2D80093F8, 0x48EFC56B31172CE1, 0xAFCA4B6A73ED7336, 0x995F04639C835D11, 0x5B3B9A208FA56837, 0x47FD72D865F2357E, 0x9E3CAC4107E83532, 0x31CC176CE59261},
{0x4AD8213DCC0EE2E4, 0x4CB861B5AE488639, 0xA51A5B14C15122A6, 0x11D3BAEAD457C643, 0x69F81BA8151F4289, 0xBBF7FD30D142B1CF, 0xEFF9B4443C1F00D, 0x3A8516A2E48A25},
{0xBA9071A25161B713, 0xD23BF87F90FB216C, 0xCCEFA630B8101BA, 0x95CCD7CE9070EAC0, 0xB8CEE68602DD9A73, 0xD60E96A7B6065216, 0xF90F1CEBF826728B, 0x1F67DF31E4041C},
{0xB826A44841FE3FCD, 0x5D362655AAD7FF01, 0x92B4DD765A16E5F5, 0xFCDB74BC0D0D0A6B, 0xF41E518CAA1A182E, 0xF07FC9B18F378B80, 0x5C70AB82A854E783, 0x1DD88FB06EF820},
{0x33EC5C7825F89FD2, 0x2199AC18FDD5A835, 0x75EAB3F2E9965093, 0x162128FDABBAA756, 0xED6618E12EA9E8AA, 0x300CF4246FAB5DDF, 0xBE8FFF323060A819, 0x147D4620F25FE7}};
static const uint64_t table_v_qr[TABLE_V_LEN][NWORDS64_FIELD] = {
{0xD640973CA6FDA33, 0x30D640973CA6FDA3, 0xA30D640973CA6FDA, 0x9630D640973CA6FD, 0xB9B362A86413EF5, 0x291A8D3DCCB3503C, 0x28AA7266E86C4410, 0x3E57A5066529FA},
{0xEF755DBC422A858, 0x90EF755DBC422A89, 0x890EF755DBC422A8, 0x8890EF755DBC422A, 0x85ACA658F4ABDC07, 0xD196BC04A493216, 0xE8EBEE1D04CCCD7F, 0x2513A427F72A8B},
{0xEADE47323668C519, 0x19083ECD7DC0E6AB, 0xABEADE47323668C5, 0xF919083ECD7DC0E6, 0xB14832196A6135B, 0x65C238AE07A19315, 0x33892F2EF24CBA75, 0xEB6BD00093E7D},
{0xF17BF9E0B28890E7, 0xF5AE5634A1BF1FA5, 0xA5F17BF9E0B28890, 0x5CF5AE5634A1BF1F, 0x25C93809E47AEFCD, 0x36BB725E0DF4FAB5, 0xE60CED675C5D80CD, 0x23712156F96CCD},
{0x1C678311555200F, 0x4D5264E0DACE9D42, 0x12A66D44591361B5, 0x5631C420E42BD0E8, 0xC7CA70C8F9037B, 0x345253296A40C7FC, 0xF44CE094886CA2C1, 0x3DAD6A1ADCE6F6},
{0xE067F0F08021B5E6, 0x11DC29B589407C3A, 0x32AEDABFA1BC2B45, 0x4481E32F9C45CD24, 0x1AA9DD8D9554F1DC, 0xB6F1C1F604160937, 0x11DEFDB2CC29708D, 0x37004EEAE4323C},
{0xE36097357D9260F6, 0x439C0A04D12BD483, 0x66E8351E74487091, 0x1421CC574D451882, 0xAEB61FAD8599E2CA, 0x48EF54E42C5C665F, 0xED1A8E11AC6A738D, 0x16259CACCC3BDD},
{0xEB10F6F4BA05720, 0x167E877244911B53, 0xB87DC936138596AE, 0x680CD578F4AED4BA, 0x1694318AE2679DB1, 0x1CEEBA16962876FF, 0x73CAE996B2A0D8BA, 0x323A5E254D4A2D},
{0xAF443325C49FC9C7, 0xF3368ED80D8E2E2D, 0x5C49FC9C7474942E, 0xCCD8E2E2DAF44332, 0x471B92FFA7F05FFB, 0x8C55AC5DD5163AAD, 0xD41A2EDB81C0F26E, 0x12B9411FE82E2A},
{0xD3467582CC3CFFCC, 0x629F4CF0C00C0C9A, 0x2CC3CFFCFCD94B2E, 0xFC00C0C9AD346758, 0x3FB8C3F63F740571, 0x2ECB1038CC7F3A82, 0xF9707F59B63157EB, 0x115F359929F1C8},
{0x3218F78BA3CBAE8D, 0x19C8ECF809D7722F, 0x7097E87F9E319229, 0x1FCB0DEE58D468E5, 0xD0E9B55BF73DCF1F, 0x1EFE4FCE69BC0416, 0xEF0693CEC4EE816A, 0xBD45626E7A975},
{0xDB0929A1BD138997, 0xF4B72083018B3DAF, 0x576F0781228D05BB, 0x59E79B4EB78D8111, 0xDA7D2741F2CC8972, 0xDF9C5CCEC9E387F5, 0x1A7CC1B8C08AB119, 0x3AFC9BC0E8ABC4},
{0xEEAAAB192225A66F, 0x3D36F4A6197D1682, 0x95351AD9A4013A92, 0x737FCA70517EACFE, 0x546BE45BE532FB91, 0xCC1BAF4DF9C83B85, 0xB7F98958BFF6909C, 0x3A327C901E0790},
{0x77FF3DD1F9D16F4B, 0x6565F407321E6DD8, 0xB8A6CD6DB5D70AF0, 0x6D5E2690BF53E87D, 0xDCA29E4346D90AC4, 0x1C4B31AB442130F8, 0xAA4B89D4E4CCD33D, 0x16F0F5CF7D95E7},
{0x8CAE1CD478CAE1CD, 0xAE1CD478CAE1CD47, 0x1CD478CAE1CD478C, 0x1878CAE1CD478CAE, 0xFAD9099BBD3A4347, 0x67F1D575139CB5BF, 0x38293A715DDCB486, 0x123FF210860EF6},
{0xA3C6570E6A3C656E, 0xC6570E6A3C6570E6, 0x570E6A3C6570E6A3, 0x266A3C6570E6A3C6, 0x28B12AECF9AF8B71, 0xDB47D42F34B82DE3, 0x9556758ADED2F1DF, 0x3AD3BE4F8540E2},
{0xCA6337B265BAB821, 0xDFD5196D5A6AC701, 0x5931D9A74BA1FF5A, 0xD0C5E74C37D3F402, 0x4D621242F79E2216, 0x57F1976F8DF43182, 0xF052D77BBE57890B, 0x26C6CA2E21363A},
{0xB4DB046E7F5DEAF1, 0x6C97A33321B84377, 0x39D110888DF1A1F9, 0x3F0E8712AF7E5A0E, 0x318610A741127CA6, 0x8FAE99D54C14A492, 0xB8E11ABEDF29D523, 0x3610D24823BB34},
{0xBCEE07864886985B, 0x893DFD453F69DBD8, 0x846663A2582C0992, 0x90BD04A8B4E03846, 0xAC8F553BEBE4AAA3, 0x21D7DE00A60E1DBA, 0xD25E1FED110FEECB, 0x2A3CA66830CF45},
{0x28AEC74774664D80, 0xEF2BB2B32771F6BB, 0x973B002353CD00B8, 0x42E8DC31DFA1491E, 0x913BAEE3CA3D9E30, 0xABF6D1605464DDAE, 0xF3BBF0EC6297B06D, 0x1F94C96F693152},
{0x13C45267DD75029B, 0x2A5B4B4FF8E045B9, 0x3A2CEEEDFA82F7D8, 0x9E84B2F89B9CECA, 0x6F9D9229FB56184A, 0xE7CFAA7031AA43EF, 0xAB559E585413397D, 0x3410E7C5B657C2},
{0xE59C162702DD0330, 0x117686788B4FC859, 0x9130D016E8C6193E, 0x95ACF6377DD58B43, 0x886E99BF17505709, 0x5785149D522C7B5C, 0x35A0C131A77598A4, 0x3CE98183E3A406},
{0xF66188E646E44D38, 0x1DDB967838C24787, 0xF0DDC924163B32D9, 0xF3085EC466F80420, 0xCDC2841D90A1671D, 0x42C7CECE348BFCC8, 0x56B81B6CB2CA11DB, 0x3514702E4A9A0A},
{0x5F325943F0BC0122, 0x19AF0969616185E4, 0x395F6F8BF027BB07, 0x3059A95AA6306371, 0x4C8AC22B51821D99, 0x8CA5493A42F7F073, 0x3159D0CAF4E03BA1, 0xBA85326656B98},
{0x355770484B8F9E78, 0x3CE74F9FB70AE2AF, 0x29C66659490DA55A, 0x4A4908AB5BFCCAB2, 0x28E847CF76744D1B, 0xD73C1DA7E9743E83, 0xBC0814A45DE92E, 0x231BAF63ED339C},
{0x8CA1F537B87311CF, 0x4C08EDED850327E5, 0x5A0D0300159AA110, 0xAA2A2BCDD5424BAF, 0xD5DE3F3F3DB4665A, 0xB414A9EB85AEED8A, 0xF42B8C9A1B8CC578, 0xFA3EDA9B597BB},
{0xA67D8C524B3E4E75, 0x86499A8DBF7A9491, 0x72F4B7F3EA4620AD, 0x4817A8E2631DE824, 0xBB8AFA3312167C4A, 0xFC6430A72CDFEFB7, 0x8D35B46A38FE2241, 0x175BFA3B8577D},
{0xCB088DAD679EF165, 0xB4C8822258637092, 0xB2C43661C46CF323, 0xB9880541F96B5BFA, 0x107BCA3032B41FAD, 0x269816DB16A086AB, 0xB5B0180593043903, 0x38FD7D2B147838},
{0x475B7B82B2D288B0, 0x22C1F565B3292571, 0x59C43DCA0D6C8F10, 0xE1F36E62396C705C, 0xF83EB8755AE3C245, 0x8AD232E4B45B2625, 0x877CD62B7C9672AD, 0x89DA6104B553C},
{0x934EEBD2D80093F8, 0x48EFC56B31172CE1, 0xAFCA4B6A73ED7336, 0x995F04639C835D11, 0x5B3B9A208FA56837, 0x47FD72D865F2357E, 0x9E3CAC4107E83532, 0x31CC176CE59261},
{0x4AD8213DCC0EE2E4, 0x4CB861B5AE488639, 0xA51A5B14C15122A6, 0x11D3BAEAD457C643, 0x69F81BA8151F4289, 0xBBF7FD30D142B1CF, 0xEFF9B4443C1F00D, 0x3A8516A2E48A25},
{0xBA9071A25161B713, 0xD23BF87F90FB216C, 0xCCEFA630B8101BA, 0x95CCD7CE9070EAC0, 0xB8CEE68602DD9A73, 0xD60E96A7B6065216, 0xF90F1CEBF826728B, 0x1F67DF31E4041C},
{0xB826A44841FE3FCD, 0x5D362655AAD7FF01, 0x92B4DD765A16E5F5, 0xFCDB74BC0D0D0A6B, 0xF41E518CAA1A182E, 0xF07FC9B18F378B80, 0x5C70AB82A854E783, 0x1DD88FB06EF820},
{0x33EC5C7825F89FD2, 0x2199AC18FDD5A835, 0x75EAB3F2E9965093, 0x162128FDABBAA756, 0xED6618E12EA9E8AA, 0x300CF4246FAB5DDF, 0xBE8FFF323060A819, 0x147D4620F25FE7}
};
static const uint64_t table_v_qnr[TABLE_V_LEN][NWORDS64_FIELD] =
{{0x6666666666666731, 0x6666666666666666, 0x6666666666666666, 0x7A66666666666666, 0x566281F7D63AE371, 0xBFF8182310E4EED8, 0x260EA261A835DB3, 0x3B5180C26A5D29},
{0x333333333333319C, 0x3333333333333333, 0x3333333333333333, 0x6333333333333333, 0x794BB3C497AE085E, 0xB747BD4AD5331DAD, 0xBBC9B92F7FE88E38, 0xA2AE8FE2D81EA},
{0x42F42F42F42F4303, 0xF42F42F42F42F42F, 0x2F42F42F42F42F42, 0x3EF42F42F42F42F4, 0xEDE69F6C16FE9C49, 0x5F14E71311869A6F, 0x4A3D210B203EC110, 0x361A6419F55969},
{0xE85E85E85E85E7E1, 0x5E85E85E85E85E85, 0x85E85E85E85E85E8, 0xBC5E85E85E85E85E, 0x160587963688731A, 0xC89C86E2D4409C4A, 0x4FFF66D7F74F792D, 0x11FD93FADD078A},
{0x2FF402FF402FF403, 0x2FF402FF402FF40, 0x402FF402FF402FF4, 0xF002FF402FF402FF, 0x10AD8E578684D15D, 0x7D8BE80CE669C6B0, 0x2F6BF0AEC5EAAB99, 0x3FBFC2D75908E7},
{0x17FA017FA017F80, 0xA017FA017FA017FA, 0xFA017FA017FA017F, 0x7FA017FA017FA017, 0x4B59B05371A2C857, 0xC201D772A296DFE0, 0x1B3AC1E2919F26D3, 0x14E64D4502A6E6},
{0x95C05529A8FEAB59, 0x595C05529A8FEAB5, 0xB595C05529A8FEAB, 0xDF595C05529A8FEA, 0x2F45F28BB8ED273E, 0xFA436C90BD54C61A, 0x1062C7B1DEDB1074, 0x315A8AEDC8909C},
{0xC06F5DDCFE428877, 0x8C06F5DDCFE42888, 0x88C06F5DDCFE4288, 0x948C06F5DDCFE428, 0xAA9C9EF112689F32, 0x53976445D5B6748E, 0x7756462EC170E4DB, 0x2C003A897F5825},
{0xFFEB87D96821E700, 0xE6FFEB87D96821E6, 0x21E6FFEB87D96821, 0x6821E6FFEB87D968, 0x536BACDAEA5360A5, 0x587DE91F62936769, 0xF9873A3AF7BA1771, 0x1AC726662E629},
{0x7D5FEC6230591FD, 0x9207D5FEC6230592, 0x59207D5FEC62305, 0x27059207D5FEC623, 0x49E0E7C0B24AB790, 0x72A0A655B60DE2BB, 0x9B0D09A6BA29F50C, 0x1D311492A73E49},
{0x3DBF0903DBF0903D, 0x903DBF0903DBF090, 0xF0903DBF0903DBF0, 0xDFF0903DBF0903DB, 0x2E57678E6F6B36FA, 0x6D14F41B551BD544, 0xA9A9EBE547506451, 0x340F0593481A65},
{0x207B7E1207B7E118, 0xE1207B7E1207B7E1, 0xB7E1207B7E1207B7, 0xE7B7E1207B7E1207, 0x8FB1896621AA9BD5, 0xACE233C79D786D08, 0x4762CA7D1868CBD4, 0x2250D8F8670982},
{0x840F89EF8D6AD1D9, 0xD860EB4F2F6A9A25, 0x59D8EC2E0086586E, 0x12947D34DB3512E9, 0xF63A898976A47748, 0x501E5E834CF73F95, 0x8EAC965E265BB2A6, 0x34B4D6B0074D55},
{0xD3DC3CD9848C0DD4, 0xF4482A22F4B792B0, 0xCE877C0F970AE966, 0xABFE2EB4BE8939B1, 0xD39F645922FB329F, 0x183041DAFBDED6FF, 0x35DDD811FD020363, 0x14AD647102E09E},
{0x9A9AC56B775830E6, 0x349D4969F781C5FE, 0x4A96A3BBEA5CCC22, 0xE413030F74832A1C, 0x4CD1307BD96041FD, 0xAFCB8545E06F5E57, 0x1C86CB1828C75997, 0xEC2C4397DD1A7},
{0x4301B37140F51F76, 0x6F2795BD0148D223, 0xC955484121E76B9F, 0x3AE35055972784AD, 0x109E0D0B1EE661B7, 0x8530AF7BBFEFB9DF, 0x2A20E1C05CCEC0E4, 0x9F5C0FEBB8ECA},
{0x4E3AF17430022B8A, 0x35839EC8DB54E2A4, 0xA3C6E03E4E9EFCD7, 0xDA418C66D7C8A36C, 0x1FD4F171FE1732C8, 0xC625B70E60138FC9, 0xA4E5092E399B6337, 0x21F760DFCCB761},
{0x5EEAD7AB9B19B13B, 0x2CD37E80CA584907, 0x38F9B3527D092219, 0x2400FFCCCCFF04B6, 0xCE2C4B82E6F44CF0, 0x83A9B6663589197B, 0x66030DD337B55803, 0xA2179BE9ED7BA},
{0xDD28279CDC678A67, 0x4D6331D441594443, 0x8D052A7E726EC043, 0x24C4928EE44B7AD9, 0x371ECF34320A1AC3, 0xF7E715563D9223CA, 0x7D4F1577FFD8B72B, 0x113FAE041A1084},
{0xE28435CF3C6F7D49, 0x2A0448B3C90AABEC, 0x4FDB34DA65E72DAE, 0x8DB6017694201827, 0xBBBDA1163D75E61D, 0x7DD994DF4E8BB61C, 0x4376D272F53F0160, 0x2F782D31FCAD7B},
{0x13CC56E70A95B922, 0x3E79A643C48D1142, 0x193B7E19EC380834, 0x1F43A718BEE0BD64, 0xAF07EEDBAAC36417, 0x1479E0460B4E85E0, 0xE997B33A457870E1, 0x12792B8A001D25},
{0xBC6BB8DF2AF20DFE, 0x56E5A0EC1FF64B46, 0x739BA13928CDC001, 0xD9A0886EDF77FAE5, 0x641A73F9F6B41ACE, 0x1DAA1F63D364ED8F, 0x797D94D0849C5333, 0xED06FE444692E},
{0x5FDF74D731C8412A, 0x6FA3CCC72BC442E7, 0xF7A328C581FF9506, 0x9D43E8D9CE513419, 0xE0969762B591CA14, 0xA7A20D5B0A226CEE, 0xE652DF72F7ACDBA7, 0x98B2737AA6855},
{0x15D2521AEA43D912, 0x7DC88B6270806BCC, 0xF1FE1E4FDEBEDBB6, 0xAFD018F26E77AD62, 0xF8BB0C784D9A7776, 0x8F933FA003570378, 0xB7A3F4080B1BBFAF, 0x3043D63A75E546},
{0x2254A8771FEA02B3, 0x8398EEA5EF546F3E, 0xA6062563B110D486, 0x5AD887813EF3AE86, 0xEAE29AC17FA58A77, 0x924599311ED77B3C, 0x3DF2835E75922318, 0x2EEB5411B26C76},
{0x9CBF7A679A9D0048, 0xB4B201453651D31E, 0xA4C91B0B01A9AE32, 0xBD873B3D5E9CDD40, 0x1869D6517CD803A, 0x5F3A2180D299CEE, 0xD46EDCD4F9A5E5C9, 0x2901D3472FBC49},
{0xBC9C88687B4C473D, 0xB37349E2D384219, 0x86A75F99B9FEA3F6, 0x32FAC92124206663, 0xBE37BE6B4BCC19CA, 0x8F77567E888968B4, 0x4308A1AB82A632E2, 0x28B00FD8816E8},
{0xF0C7DF924D5127BA, 0xCB86F4707F9FBAC5, 0xB643FD9963502BF, 0x5125F52EC4BF48C7, 0x87F7A3330AF723A0, 0x1455E18791E932FD, 0x4DE936B1F7BAE4CF, 0x6F35FFA98F53D},
{0x459FB6EF424D1859, 0xF492057CEBD9391E, 0xE70ACB8F885C8084, 0xCEBCCFF5FF922454, 0xEA056AA88BDD2C5B, 0xB33F747126069D2B, 0xABC8F606165AB077, 0x280CA098BAD483},
{0xAD7B42377A2CF64A, 0x62877A76DB1B5C49, 0xDAAFDC58FABA0793, 0x6501BFB81B604B74, 0xA5EC0D8847E461DF, 0xE730BEA141B807F7, 0x16209BF6A0544D52, 0x1C131448A178B3},
{0xF09679A75D6EDB8A, 0x85E0E32FA20333FD, 0x659E89AE27506F5D, 0xCBE8610A2E1C126F, 0xCA328C6CB821E1A4, 0xB0F6B45C68433733, 0x996850439E5A4FA7, 0x3D91026425288B},
{0xC70416DFD912112, 0x7B03BDB79F9194DC, 0x1ACDFCB1F1986D14, 0x572978ED23C5581B, 0xFB1B4CAD724370B0, 0x7DCCA0FBB9D5A84A, 0xA33D15155FB6D48B, 0x861CA17970496},
{0x22BCBF7871766C3A, 0x9395C19D8E87CC4C, 0xB92EF7084D0FEBD8, 0x8A60E143C87DB915, 0x3FDCB6ED258F6167, 0xFB9943E3BF11D380, 0xE116C209F87D2108, 0xE76DDE2391409},
{0xC8A69E75B7B72831, 0x300BCE8A5E86484D, 0x34F0183CB8FBECCB, 0x590030B5DC767075, 0x2D8B65503007FE01, 0x8F397E3E796F3B98, 0xC77FB29679EAF434, 0x13554730291BD2}};
static const uint64_t table_v_qnr[TABLE_V_LEN][NWORDS64_FIELD] = {
{0x6666666666666731, 0x6666666666666666, 0x6666666666666666, 0x7A66666666666666, 0x566281F7D63AE371, 0xBFF8182310E4EED8, 0x260EA261A835DB3, 0x3B5180C26A5D29},
{0x333333333333319C, 0x3333333333333333, 0x3333333333333333, 0x6333333333333333, 0x794BB3C497AE085E, 0xB747BD4AD5331DAD, 0xBBC9B92F7FE88E38, 0xA2AE8FE2D81EA},
{0x42F42F42F42F4303, 0xF42F42F42F42F42F, 0x2F42F42F42F42F42, 0x3EF42F42F42F42F4, 0xEDE69F6C16FE9C49, 0x5F14E71311869A6F, 0x4A3D210B203EC110, 0x361A6419F55969},
{0xE85E85E85E85E7E1, 0x5E85E85E85E85E85, 0x85E85E85E85E85E8, 0xBC5E85E85E85E85E, 0x160587963688731A, 0xC89C86E2D4409C4A, 0x4FFF66D7F74F792D, 0x11FD93FADD078A},
{0x2FF402FF402FF403, 0x2FF402FF402FF40, 0x402FF402FF402FF4, 0xF002FF402FF402FF, 0x10AD8E578684D15D, 0x7D8BE80CE669C6B0, 0x2F6BF0AEC5EAAB99, 0x3FBFC2D75908E7},
{0x17FA017FA017F80, 0xA017FA017FA017FA, 0xFA017FA017FA017F, 0x7FA017FA017FA017, 0x4B59B05371A2C857, 0xC201D772A296DFE0, 0x1B3AC1E2919F26D3, 0x14E64D4502A6E6},
{0x95C05529A8FEAB59, 0x595C05529A8FEAB5, 0xB595C05529A8FEAB, 0xDF595C05529A8FEA, 0x2F45F28BB8ED273E, 0xFA436C90BD54C61A, 0x1062C7B1DEDB1074, 0x315A8AEDC8909C},
{0xC06F5DDCFE428877, 0x8C06F5DDCFE42888, 0x88C06F5DDCFE4288, 0x948C06F5DDCFE428, 0xAA9C9EF112689F32, 0x53976445D5B6748E, 0x7756462EC170E4DB, 0x2C003A897F5825},
{0xFFEB87D96821E700, 0xE6FFEB87D96821E6, 0x21E6FFEB87D96821, 0x6821E6FFEB87D968, 0x536BACDAEA5360A5, 0x587DE91F62936769, 0xF9873A3AF7BA1771, 0x1AC726662E629},
{0x7D5FEC6230591FD, 0x9207D5FEC6230592, 0x59207D5FEC62305, 0x27059207D5FEC623, 0x49E0E7C0B24AB790, 0x72A0A655B60DE2BB, 0x9B0D09A6BA29F50C, 0x1D311492A73E49},
{0x3DBF0903DBF0903D, 0x903DBF0903DBF090, 0xF0903DBF0903DBF0, 0xDFF0903DBF0903DB, 0x2E57678E6F6B36FA, 0x6D14F41B551BD544, 0xA9A9EBE547506451, 0x340F0593481A65},
{0x207B7E1207B7E118, 0xE1207B7E1207B7E1, 0xB7E1207B7E1207B7, 0xE7B7E1207B7E1207, 0x8FB1896621AA9BD5, 0xACE233C79D786D08, 0x4762CA7D1868CBD4, 0x2250D8F8670982},
{0x840F89EF8D6AD1D9, 0xD860EB4F2F6A9A25, 0x59D8EC2E0086586E, 0x12947D34DB3512E9, 0xF63A898976A47748, 0x501E5E834CF73F95, 0x8EAC965E265BB2A6, 0x34B4D6B0074D55},
{0xD3DC3CD9848C0DD4, 0xF4482A22F4B792B0, 0xCE877C0F970AE966, 0xABFE2EB4BE8939B1, 0xD39F645922FB329F, 0x183041DAFBDED6FF, 0x35DDD811FD020363, 0x14AD647102E09E},
{0x9A9AC56B775830E6, 0x349D4969F781C5FE, 0x4A96A3BBEA5CCC22, 0xE413030F74832A1C, 0x4CD1307BD96041FD, 0xAFCB8545E06F5E57, 0x1C86CB1828C75997, 0xEC2C4397DD1A7},
{0x4301B37140F51F76, 0x6F2795BD0148D223, 0xC955484121E76B9F, 0x3AE35055972784AD, 0x109E0D0B1EE661B7, 0x8530AF7BBFEFB9DF, 0x2A20E1C05CCEC0E4, 0x9F5C0FEBB8ECA},
{0x4E3AF17430022B8A, 0x35839EC8DB54E2A4, 0xA3C6E03E4E9EFCD7, 0xDA418C66D7C8A36C, 0x1FD4F171FE1732C8, 0xC625B70E60138FC9, 0xA4E5092E399B6337, 0x21F760DFCCB761},
{0x5EEAD7AB9B19B13B, 0x2CD37E80CA584907, 0x38F9B3527D092219, 0x2400FFCCCCFF04B6, 0xCE2C4B82E6F44CF0, 0x83A9B6663589197B, 0x66030DD337B55803, 0xA2179BE9ED7BA},
{0xDD28279CDC678A67, 0x4D6331D441594443, 0x8D052A7E726EC043, 0x24C4928EE44B7AD9, 0x371ECF34320A1AC3, 0xF7E715563D9223CA, 0x7D4F1577FFD8B72B, 0x113FAE041A1084},
{0xE28435CF3C6F7D49, 0x2A0448B3C90AABEC, 0x4FDB34DA65E72DAE, 0x8DB6017694201827, 0xBBBDA1163D75E61D, 0x7DD994DF4E8BB61C, 0x4376D272F53F0160, 0x2F782D31FCAD7B},
{0x13CC56E70A95B922, 0x3E79A643C48D1142, 0x193B7E19EC380834, 0x1F43A718BEE0BD64, 0xAF07EEDBAAC36417, 0x1479E0460B4E85E0, 0xE997B33A457870E1, 0x12792B8A001D25},
{0xBC6BB8DF2AF20DFE, 0x56E5A0EC1FF64B46, 0x739BA13928CDC001, 0xD9A0886EDF77FAE5, 0x641A73F9F6B41ACE, 0x1DAA1F63D364ED8F, 0x797D94D0849C5333, 0xED06FE444692E},
{0x5FDF74D731C8412A, 0x6FA3CCC72BC442E7, 0xF7A328C581FF9506, 0x9D43E8D9CE513419, 0xE0969762B591CA14, 0xA7A20D5B0A226CEE, 0xE652DF72F7ACDBA7, 0x98B2737AA6855},
{0x15D2521AEA43D912, 0x7DC88B6270806BCC, 0xF1FE1E4FDEBEDBB6, 0xAFD018F26E77AD62, 0xF8BB0C784D9A7776, 0x8F933FA003570378, 0xB7A3F4080B1BBFAF, 0x3043D63A75E546},
{0x2254A8771FEA02B3, 0x8398EEA5EF546F3E, 0xA6062563B110D486, 0x5AD887813EF3AE86, 0xEAE29AC17FA58A77, 0x924599311ED77B3C, 0x3DF2835E75922318, 0x2EEB5411B26C76},
{0x9CBF7A679A9D0048, 0xB4B201453651D31E, 0xA4C91B0B01A9AE32, 0xBD873B3D5E9CDD40, 0x1869D6517CD803A, 0x5F3A2180D299CEE, 0xD46EDCD4F9A5E5C9, 0x2901D3472FBC49},
{0xBC9C88687B4C473D, 0xB37349E2D384219, 0x86A75F99B9FEA3F6, 0x32FAC92124206663, 0xBE37BE6B4BCC19CA, 0x8F77567E888968B4, 0x4308A1AB82A632E2, 0x28B00FD8816E8},
{0xF0C7DF924D5127BA, 0xCB86F4707F9FBAC5, 0xB643FD9963502BF, 0x5125F52EC4BF48C7, 0x87F7A3330AF723A0, 0x1455E18791E932FD, 0x4DE936B1F7BAE4CF, 0x6F35FFA98F53D},
{0x459FB6EF424D1859, 0xF492057CEBD9391E, 0xE70ACB8F885C8084, 0xCEBCCFF5FF922454, 0xEA056AA88BDD2C5B, 0xB33F747126069D2B, 0xABC8F606165AB077, 0x280CA098BAD483},
{0xAD7B42377A2CF64A, 0x62877A76DB1B5C49, 0xDAAFDC58FABA0793, 0x6501BFB81B604B74, 0xA5EC0D8847E461DF, 0xE730BEA141B807F7, 0x16209BF6A0544D52, 0x1C131448A178B3},
{0xF09679A75D6EDB8A, 0x85E0E32FA20333FD, 0x659E89AE27506F5D, 0xCBE8610A2E1C126F, 0xCA328C6CB821E1A4, 0xB0F6B45C68433733, 0x996850439E5A4FA7, 0x3D91026425288B},
{0xC70416DFD912112, 0x7B03BDB79F9194DC, 0x1ACDFCB1F1986D14, 0x572978ED23C5581B, 0xFB1B4CAD724370B0, 0x7DCCA0FBB9D5A84A, 0xA33D15155FB6D48B, 0x861CA17970496},
{0x22BCBF7871766C3A, 0x9395C19D8E87CC4C, 0xB92EF7084D0FEBD8, 0x8A60E143C87DB915, 0x3FDCB6ED258F6167, 0xFB9943E3BF11D380, 0xE116C209F87D2108, 0xE76DDE2391409},
{0xC8A69E75B7B72831, 0x300BCE8A5E86484D, 0x34F0183CB8FBECCB, 0x590030B5DC767075, 0x2D8B65503007FE01, 0x8F397E3E796F3B98, 0xC77FB29679EAF434, 0x13554730291BD2}
};
static const uint64_t v_3_torsion[20][2 * NWORDS64_FIELD] =
{{0x9999999999999ACA, 0x9999999999999999, 0x9999999999999999, 0xE199999999999999, 0xF80F9506B04F6159, 0x922628D05B98276C, 0x536E7BDA3A893A25, 0x38C6C682DEFCAE, 0xCCCCCCCCCCCCCC67, 0xCCCCCCCCCCCCCCCC, 0xCCCCCCCCCCCCCCCC, 0x98CCCCCCCCCCCCCC, 0x5E52ECF125EB8217, 0x2DD1EF52B54CC76B, 0xAEF26E4BDFFA238E, 0x28ABA3F8B607A},
{0xB61A6449E59BB678, 0xE59BB61A6449E59B, 0x6449E59BB61A6449, 0x161A6449E59BB61A, 0xB0A7A696AD14F403, 0x5908519429BF6752, 0xF8F5C2FDB95D626B, 0x3415A91EB9B01B, 0x59BB61A6449E5991, 0x449E59BB61A6449E, 0x61A6449E59BB61A6, 0xEDBB61A6449E59BB, 0xDCBBFD66B1210ED0, 0xD1759BAF69F0DE7F, 0x151E605BC94FFF1C, 0x1AF11E41BC9044},
{0x865EFC865EFC868A, 0x5EFC865EFC865EFC, 0xFC865EFC865EFC86, 0xCE5EFC865EFC865E, 0x4CC228DC36501857, 0x73987670F8421161, 0xE0DF934DDA9372B7, 0x2EFD8AF527F647, 0x548FA3548FA3547A, 0x8FA3548FA3548FA3, 0xA3548FA3548FA354, 0x5C8FA3548FA3548F, 0x370CE767DB69F0A1, 0x148A42FD9FA8E75E, 0x95D3497A1836567A, 0x3B176D3CEE7B7D},
{0x50217FB6E959A5E1, 0x55D744B5F5B8D09B, 0xF7A01245A9968DFD, 0x5E2ED28291CBD92B, 0x327D6A4F12ED9197, 0x22F38DE9B94342A8, 0xF08F9207C0BC4954, 0x92CA7D85CB62, 0x554517694148E5E0, 0x810BFDB74ACD2E40, 0xAEBA25AFADC684DA, 0x3D00922D4CB46FEA, 0x9B6A27893DA502ED, 0x70CDC63D75720D1A, 0x79E291279150591, 0x1EF28157438CF6},
{0x59D483698ADF25AD, 0xDF259D483698ADF2, 0x98ADF259D483698A, 0x47698ADF259D4836, 0x8A409FE323B0C564, 0x7776BA73BB1425E9, 0xA9C30185C47DDDD5, 0x17CB3BFFF6729E, 0x6F92CEA41B4C56F1, 0x4C56F92CEA41B4C5, 0x41B4C56F92CEA41B, 0xE2A41B4C56F92CEA, 0x9D076460B8435788, 0x54F113B72EB92D94, 0x2A66E44EFC731303, 0x12A4AB560F3F66},
{0x2B1FB984943A94A8, 0x30572CDCDFF75824, 0x86B44D20E248E0BD, 0x91D67FBFB355D2A2, 0x1FB62ABAE68FD35D, 0x3C9EB762B7B42EE1, 0x9F02146D035C6473, 0x2E16E82F80CE94, 0x57721BBE9E5A5800, 0xA2061AF8C6275649, 0x3BD12A9F2030397F, 0x11812DB680FC4074, 0xE65278C2B095007B, 0x8F2E2CBAE91FE5D5, 0xED8F5676C276CA45, 0x3DF6D70A1D206A},
{0xBE8AB88AA30ECFE7, 0x4BA78C308192D1B7, 0xB3E24AC5F8070CA1, 0x96351F2D30F7BBD, 0x81FEFCEA948AD196, 0xD3C5B4543AD9805F, 0xA75812F48753D9, 0x1724C5EDAB3470, 0x2827F23CACB56FB9, 0x157BD32FB57A7B7, 0x70A9DAFDB132D060, 0x792BEEB65C0F9BF7, 0xE56FC183B1F50CE1, 0xCCAD12C0789DBF02, 0x8C2146875FF342E2, 0x1CE0B3C0517507},
{0x49B33CFF3F381BC6, 0xD8CAC1728CCEDAAE, 0x1DF2FD00097B2467, 0xAB713DCFD459086, 0x8836E5EA1B2EDAB, 0x1716275997ADF384, 0x191CA247A36D2F50, 0x32176EFFF620B5, 0x4C8D46F27B6D17EC, 0x50F8ADEAE3D0F0C7, 0x545DC5F4131C3561, 0xE5B904096E80374E, 0xA86F14DB302AE72D, 0x8F42BC329DB7D7E0, 0x83BAE6D9FEE5F302, 0x31094190A0F887},
{0x8EB074F53A76A870, 0xB126FDBA6CC46493, 0x555A9BBF86580EF5, 0x2D766D1384CC6DD9, 0x488C1D0E043C69F6, 0xE46574481370F9B8, 0x20011A2950633B25, 0x2C90D406DC97FF, 0x25760E200D5A3CC9, 0x5B029C9D13C41968, 0x4CF262816A003763, 0xECB895F7DEFD5B79, 0x5500D603F7586E63, 0xD3B73E937238582B, 0xE0717E4434F561B4, 0x24B97B8A231B62},
{0x3B59E87672CD3132, 0x39065FDDB46E42BB, 0xDFF1DBFCEE9FB3C5, 0x95D0A17ADF5B0686, 0x4F4AE55C15F6F6, 0xEC7A661AF31BEEA2, 0xCA7A05464470274, 0x32630B4C55211E, 0x9DB227BAE1A18E5E, 0x2D8003402FC924D9, 0xDBBA9E0412D57B42, 0xE3590E03813384, 0x50E5FD1EE6160BE7, 0x319EE53F2DE7E963, 0xAFBEDCC8195A0FE7, 0x1D66C22AE5E03D},
{0xFA1D721B8012AD24, 0x4D5A34CA856360AA, 0x2C74166DA03E082F, 0xA334C1A0A8C0EECA, 0x4BD3029C76081336, 0xC17E91F7FE1620AB, 0x602C6464DF6D7B5A, 0x37C56195A01609, 0xF42E70CB53B77D89, 0x971CD3CDB95DCA98, 0x98BED2110CEA97D7, 0x29E8E40FDE89CEA0, 0x66762394F501B5D, 0x768E393C98EDB0DC, 0x7B7177B9782A051C, 0x2419F31B5536B7},
{0x6B9078F75FB9FD5A, 0xAAE697DEF085EE62, 0x55F0635BB0920820, 0xB6EB4C44F59DA609, 0x9D20534E797B55E3, 0xE586320878C2E00C, 0x4B2C04D2265832BF, 0x2B7A08CADF8ABE, 0xA28AD65405737E37, 0x1A7AD3DA645AE6C, 0xA007C768042513DE, 0xB862E5834961B9AB, 0xD751FD817FF50BD6, 0xD40A969925029B74, 0x38326A08AA3FE933, 0x33A720FE49B1C0},
{0x6F33A8DC20803BD8, 0x2846C4B267C2FEA9, 0x3007D269048CB91D, 0x149AF087F10343DC, 0xA411643250BFE57D, 0xFE05DA28BEBBD6A2, 0xA1CC30AB16469EDF, 0x73147428B8D6E, 0x14144FB077BA07EC, 0xBDDB35BAB1D76D69, 0x161ED689F2678887, 0x635E2E3996327A7D, 0xEF1D6C7CA5686991, 0x50B90BE915F46926, 0x1CA4E335B9AB5FD5, 0x27BAA66DCED0C5},
{0xEFA7AC2F83918F15, 0x1180A29870F3D459, 0x90347A6E04DDB73E, 0x80D765C86450E8FF, 0xB872718F0F19F98D, 0xD6A86F096DCF4922, 0xB38BB34120254D9, 0x2E5A1621B615F2, 0xB2D181BD4FA52AA2, 0xDC904B3EB8AF6F02, 0xD6B25DF9558317E8, 0x85BF914F31A23BAC, 0xBDA3E9AB557B29B7, 0x5CD5E1D426B1789D, 0x8A6AED659E678CD3, 0x1C56D6E1BB93F5},
{0x924E6058D015A38D, 0x1E2EC7DD7A5132B7, 0xA97C2194346DA32D, 0x41EF1F31CD51333B, 0xFB89E6E30C1162AA, 0x4061678E5962580A, 0x9ECCCCB3B6FAD5A, 0x37AF58627A887A, 0xE8F5D903F0BD0269, 0x200E1FFA8489B9DA, 0xDE882C8D3156A460, 0x8C4DABC11F877458, 0xD54C3B40CD538F2F, 0x41674635284DFEBB, 0xAD9B8330BFF569FC, 0x30C2633BF078F7},
{0x75C1E6ED473130D0, 0xFD624B7CC04D355F, 0x313DC4BCA820911E, 0x449D8112D71CF106, 0x23A25A83664B420E, 0x16A55C6AF6910691, 0xDA58FB0631B2EAD0, 0x2D42B72E1FA0F5, 0x4AF98FC17BA992CE, 0x19C1F944FD5AB7F4, 0x68ACC73E0CE942CF, 0x7B3F9FA6C110FEFD, 0x3DEFD9B6CFCF2AD2, 0x4B080446336C5FA5, 0x19508DFD60080814, 0xFD442DBA88642},
{0x4EE43F3D8CAC1374, 0xAF2E7784E2460F7, 0x50133AD8519FCCA1, 0xBDB81ECD10C888CF, 0x675791FE9112FBA, 0x364B5F4D282C51A3, 0xA3A53FD5546E97E0, 0x261C6F73A8BA64, 0x13DE8B19DF5E0FEE, 0x1D05A6FE505FEA21, 0x634E634AA1C25DBB, 0x2C49E6E62282B432, 0xE989B2E0D9775E22, 0x104ABC59A97037E8, 0x3DFAB907857260E, 0x3B8179D525D960},
{0xAA3BFB6CB8587768, 0x515E32FD38308C38, 0x927E612E9CE18C76, 0x13B2195A5D867C54, 0x857274100A6ECFD0, 0x10CAD97274DDC646, 0x30BCDB9A79ECA27, 0x7F0790BC050BA, 0x67F4FD27FF7B7A3B, 0x7528EF9DFC6790F9, 0xD34442AA02F00A58, 0x51935D736DE84027, 0xFEA3DCBAF9002F2, 0xB3D055C2572AD741, 0x9F0EF6D70050CCC5, 0x10611302FDA1B4},
{0x8894D7E86C5358CF, 0xE01ED56C2E374D80, 0x1EB04AACFBB0B60D, 0x1B0F1031360154CD, 0x52257CF78935DF2, 0xD1759C3E61E7823C, 0xC5CBD367AD3EB0AB, 0x377C52E4424CF4, 0xED5FFE6B5FB024BD, 0x65B8965C7A3F1BB, 0x61A0E4FB6BAAF40F, 0xD8ACB4A3CC9A6C24, 0x38FAAD404A5D6211, 0xF59F595458B10D72, 0x13FDB0B2371936A0, 0x1934F680EC8F88},
{0xF6DC60A5C5734661, 0x9CD9E9A6DA083A88, 0xEDA465D0EAA7F9BB, 0x87FEE132D788E4CA, 0x94D57ED92F0D0A7B, 0xA157AC0056BDBFE8, 0x62DAF28EE0E30FC9, 0x10E9FA4557999D, 0x78942F9DE083A353, 0x5FDAC52AEBA63CE5, 0x905BC434EA6102CF, 0x9CC2E0667372C509, 0xE22094C33879AFDC, 0x820B3999B77E5E28, 0x7076A18C8D100A7D, 0x1B55229ADA2623}};
static const uint64_t v_3_torsion[20][2 * NWORDS64_FIELD] = {
{0x9999999999999ACA, 0x9999999999999999, 0x9999999999999999, 0xE199999999999999, 0xF80F9506B04F6159, 0x922628D05B98276C, 0x536E7BDA3A893A25, 0x38C6C682DEFCAE, 0xCCCCCCCCCCCCCC67, 0xCCCCCCCCCCCCCCCC, 0xCCCCCCCCCCCCCCCC, 0x98CCCCCCCCCCCCCC, 0x5E52ECF125EB8217, 0x2DD1EF52B54CC76B, 0xAEF26E4BDFFA238E, 0x28ABA3F8B607A},
{0xB61A6449E59BB678, 0xE59BB61A6449E59B, 0x6449E59BB61A6449, 0x161A6449E59BB61A, 0xB0A7A696AD14F403, 0x5908519429BF6752, 0xF8F5C2FDB95D626B, 0x3415A91EB9B01B, 0x59BB61A6449E5991, 0x449E59BB61A6449E, 0x61A6449E59BB61A6, 0xEDBB61A6449E59BB, 0xDCBBFD66B1210ED0, 0xD1759BAF69F0DE7F, 0x151E605BC94FFF1C, 0x1AF11E41BC9044},
{0x865EFC865EFC868A, 0x5EFC865EFC865EFC, 0xFC865EFC865EFC86, 0xCE5EFC865EFC865E, 0x4CC228DC36501857, 0x73987670F8421161, 0xE0DF934DDA9372B7, 0x2EFD8AF527F647, 0x548FA3548FA3547A, 0x8FA3548FA3548FA3, 0xA3548FA3548FA354, 0x5C8FA3548FA3548F, 0x370CE767DB69F0A1, 0x148A42FD9FA8E75E, 0x95D3497A1836567A, 0x3B176D3CEE7B7D},
{0x50217FB6E959A5E1, 0x55D744B5F5B8D09B, 0xF7A01245A9968DFD, 0x5E2ED28291CBD92B, 0x327D6A4F12ED9197, 0x22F38DE9B94342A8, 0xF08F9207C0BC4954, 0x92CA7D85CB62, 0x554517694148E5E0, 0x810BFDB74ACD2E40, 0xAEBA25AFADC684DA, 0x3D00922D4CB46FEA, 0x9B6A27893DA502ED, 0x70CDC63D75720D1A, 0x79E291279150591, 0x1EF28157438CF6},
{0x59D483698ADF25AD, 0xDF259D483698ADF2, 0x98ADF259D483698A, 0x47698ADF259D4836, 0x8A409FE323B0C564, 0x7776BA73BB1425E9, 0xA9C30185C47DDDD5, 0x17CB3BFFF6729E, 0x6F92CEA41B4C56F1, 0x4C56F92CEA41B4C5, 0x41B4C56F92CEA41B, 0xE2A41B4C56F92CEA, 0x9D076460B8435788, 0x54F113B72EB92D94, 0x2A66E44EFC731303, 0x12A4AB560F3F66},
{0x2B1FB984943A94A8, 0x30572CDCDFF75824, 0x86B44D20E248E0BD, 0x91D67FBFB355D2A2, 0x1FB62ABAE68FD35D, 0x3C9EB762B7B42EE1, 0x9F02146D035C6473, 0x2E16E82F80CE94, 0x57721BBE9E5A5800, 0xA2061AF8C6275649, 0x3BD12A9F2030397F, 0x11812DB680FC4074, 0xE65278C2B095007B, 0x8F2E2CBAE91FE5D5, 0xED8F5676C276CA45, 0x3DF6D70A1D206A},
{0xBE8AB88AA30ECFE7, 0x4BA78C308192D1B7, 0xB3E24AC5F8070CA1, 0x96351F2D30F7BBD, 0x81FEFCEA948AD196, 0xD3C5B4543AD9805F, 0xA75812F48753D9, 0x1724C5EDAB3470, 0x2827F23CACB56FB9, 0x157BD32FB57A7B7, 0x70A9DAFDB132D060, 0x792BEEB65C0F9BF7, 0xE56FC183B1F50CE1, 0xCCAD12C0789DBF02, 0x8C2146875FF342E2, 0x1CE0B3C0517507},
{0x49B33CFF3F381BC6, 0xD8CAC1728CCEDAAE, 0x1DF2FD00097B2467, 0xAB713DCFD459086, 0x8836E5EA1B2EDAB, 0x1716275997ADF384, 0x191CA247A36D2F50, 0x32176EFFF620B5, 0x4C8D46F27B6D17EC, 0x50F8ADEAE3D0F0C7, 0x545DC5F4131C3561, 0xE5B904096E80374E, 0xA86F14DB302AE72D, 0x8F42BC329DB7D7E0, 0x83BAE6D9FEE5F302, 0x31094190A0F887},
{0x8EB074F53A76A870, 0xB126FDBA6CC46493, 0x555A9BBF86580EF5, 0x2D766D1384CC6DD9, 0x488C1D0E043C69F6, 0xE46574481370F9B8, 0x20011A2950633B25, 0x2C90D406DC97FF, 0x25760E200D5A3CC9, 0x5B029C9D13C41968, 0x4CF262816A003763, 0xECB895F7DEFD5B79, 0x5500D603F7586E63, 0xD3B73E937238582B, 0xE0717E4434F561B4, 0x24B97B8A231B62},
{0x3B59E87672CD3132, 0x39065FDDB46E42BB, 0xDFF1DBFCEE9FB3C5, 0x95D0A17ADF5B0686, 0x4F4AE55C15F6F6, 0xEC7A661AF31BEEA2, 0xCA7A05464470274, 0x32630B4C55211E, 0x9DB227BAE1A18E5E, 0x2D8003402FC924D9, 0xDBBA9E0412D57B42, 0xE3590E03813384, 0x50E5FD1EE6160BE7, 0x319EE53F2DE7E963, 0xAFBEDCC8195A0FE7, 0x1D66C22AE5E03D},
{0xFA1D721B8012AD24, 0x4D5A34CA856360AA, 0x2C74166DA03E082F, 0xA334C1A0A8C0EECA, 0x4BD3029C76081336, 0xC17E91F7FE1620AB, 0x602C6464DF6D7B5A, 0x37C56195A01609, 0xF42E70CB53B77D89, 0x971CD3CDB95DCA98, 0x98BED2110CEA97D7, 0x29E8E40FDE89CEA0, 0x66762394F501B5D, 0x768E393C98EDB0DC, 0x7B7177B9782A051C, 0x2419F31B5536B7},
{0x6B9078F75FB9FD5A, 0xAAE697DEF085EE62, 0x55F0635BB0920820, 0xB6EB4C44F59DA609, 0x9D20534E797B55E3, 0xE586320878C2E00C, 0x4B2C04D2265832BF, 0x2B7A08CADF8ABE, 0xA28AD65405737E37, 0x1A7AD3DA645AE6C, 0xA007C768042513DE, 0xB862E5834961B9AB, 0xD751FD817FF50BD6, 0xD40A969925029B74, 0x38326A08AA3FE933, 0x33A720FE49B1C0},
{0x6F33A8DC20803BD8, 0x2846C4B267C2FEA9, 0x3007D269048CB91D, 0x149AF087F10343DC, 0xA411643250BFE57D, 0xFE05DA28BEBBD6A2, 0xA1CC30AB16469EDF, 0x73147428B8D6E, 0x14144FB077BA07EC, 0xBDDB35BAB1D76D69, 0x161ED689F2678887, 0x635E2E3996327A7D, 0xEF1D6C7CA5686991, 0x50B90BE915F46926, 0x1CA4E335B9AB5FD5, 0x27BAA66DCED0C5},
{0xEFA7AC2F83918F15, 0x1180A29870F3D459, 0x90347A6E04DDB73E, 0x80D765C86450E8FF, 0xB872718F0F19F98D, 0xD6A86F096DCF4922, 0xB38BB34120254D9, 0x2E5A1621B615F2, 0xB2D181BD4FA52AA2, 0xDC904B3EB8AF6F02, 0xD6B25DF9558317E8, 0x85BF914F31A23BAC, 0xBDA3E9AB557B29B7, 0x5CD5E1D426B1789D, 0x8A6AED659E678CD3, 0x1C56D6E1BB93F5},
{0x924E6058D015A38D, 0x1E2EC7DD7A5132B7, 0xA97C2194346DA32D, 0x41EF1F31CD51333B, 0xFB89E6E30C1162AA, 0x4061678E5962580A, 0x9ECCCCB3B6FAD5A, 0x37AF58627A887A, 0xE8F5D903F0BD0269, 0x200E1FFA8489B9DA, 0xDE882C8D3156A460, 0x8C4DABC11F877458, 0xD54C3B40CD538F2F, 0x41674635284DFEBB, 0xAD9B8330BFF569FC, 0x30C2633BF078F7},
{0x75C1E6ED473130D0, 0xFD624B7CC04D355F, 0x313DC4BCA820911E, 0x449D8112D71CF106, 0x23A25A83664B420E, 0x16A55C6AF6910691, 0xDA58FB0631B2EAD0, 0x2D42B72E1FA0F5, 0x4AF98FC17BA992CE, 0x19C1F944FD5AB7F4, 0x68ACC73E0CE942CF, 0x7B3F9FA6C110FEFD, 0x3DEFD9B6CFCF2AD2, 0x4B080446336C5FA5, 0x19508DFD60080814, 0xFD442DBA88642},
{0x4EE43F3D8CAC1374, 0xAF2E7784E2460F7, 0x50133AD8519FCCA1, 0xBDB81ECD10C888CF, 0x675791FE9112FBA, 0x364B5F4D282C51A3, 0xA3A53FD5546E97E0, 0x261C6F73A8BA64, 0x13DE8B19DF5E0FEE, 0x1D05A6FE505FEA21, 0x634E634AA1C25DBB, 0x2C49E6E62282B432, 0xE989B2E0D9775E22, 0x104ABC59A97037E8, 0x3DFAB907857260E, 0x3B8179D525D960},
{0xAA3BFB6CB8587768, 0x515E32FD38308C38, 0x927E612E9CE18C76, 0x13B2195A5D867C54, 0x857274100A6ECFD0, 0x10CAD97274DDC646, 0x30BCDB9A79ECA27, 0x7F0790BC050BA, 0x67F4FD27FF7B7A3B, 0x7528EF9DFC6790F9, 0xD34442AA02F00A58, 0x51935D736DE84027, 0xFEA3DCBAF9002F2, 0xB3D055C2572AD741, 0x9F0EF6D70050CCC5, 0x10611302FDA1B4},
{0x8894D7E86C5358CF, 0xE01ED56C2E374D80, 0x1EB04AACFBB0B60D, 0x1B0F1031360154CD, 0x52257CF78935DF2, 0xD1759C3E61E7823C, 0xC5CBD367AD3EB0AB, 0x377C52E4424CF4, 0xED5FFE6B5FB024BD, 0x65B8965C7A3F1BB, 0x61A0E4FB6BAAF40F, 0xD8ACB4A3CC9A6C24, 0x38FAAD404A5D6211, 0xF59F595458B10D72, 0x13FDB0B2371936A0, 0x1934F680EC8F88},
{0xF6DC60A5C5734661, 0x9CD9E9A6DA083A88, 0xEDA465D0EAA7F9BB, 0x87FEE132D788E4CA, 0x94D57ED92F0D0A7B, 0xA157AC0056BDBFE8, 0x62DAF28EE0E30FC9, 0x10E9FA4557999D, 0x78942F9DE083A353, 0x5FDAC52AEBA63CE5, 0x905BC434EA6102CF, 0x9CC2E0667372C509, 0xE22094C33879AFDC, 0x820B3999B77E5E28, 0x7076A18C8D100A7D, 0x1B55229ADA2623}
};
// Setting up macro defines and including GF(p), GF(p^2), curve, isogeny and kex functions
#define fpcopy fpcopy503

View File

@ -1,293 +1,293 @@
/********************************************************************************************
* SIDH: an efficient supersingular isogeny cryptography library
*
* Abstract: internal header file for P503
*********************************************************************************************/
#ifndef P503_INTERNAL_H
#define P503_INTERNAL_H
#include "../config.h"
#if (TARGET == TARGET_AMD64)
#define NWORDS_FIELD 8 // Number of words of a 503-bit field element
#define p503_ZERO_WORDS 3 // Number of "0" digits in the least significant part of p503 + 1
#elif (TARGET == TARGET_x86)
#define NWORDS_FIELD 16
#define p503_ZERO_WORDS 7
#elif (TARGET == TARGET_ARM)
#define NWORDS_FIELD 16
#define p503_ZERO_WORDS 7
#elif (TARGET == TARGET_ARM64)
#define NWORDS_FIELD 8
#define p503_ZERO_WORDS 3
#endif
// Basic constants
#define NBITS_FIELD 503
#define MAXBITS_FIELD 512
#define MAXWORDS_FIELD ((MAXBITS_FIELD + RADIX - 1) / RADIX) // Max. number of words to represent field elements
#define NWORDS64_FIELD ((NBITS_FIELD + 63) / 64) // Number of 64-bit words of a 503-bit field element
#define NBITS_ORDER 256
#define NWORDS_ORDER ((NBITS_ORDER + RADIX - 1) / RADIX) // Number of words of oA and oB, where oA and oB are the subgroup orders of Alice and Bob, resp.
#define NWORDS64_ORDER ((NBITS_ORDER + 63) / 64) // Number of 64-bit words of a 256-bit element
#define MAXBITS_ORDER NBITS_ORDER
#define ALICE 0
#define BOB 1
#define OALICE_BITS 250
#define OBOB_BITS 253
#define OBOB_EXPON 159
#define MASK_ALICE 0x03
#define MASK_BOB 0x0F
#define PRIME p503
#define PARAM_A 6
#define PARAM_C 1
// Fixed parameters for isogeny tree computation
#define MAX_INT_POINTS_ALICE 7
#define MAX_INT_POINTS_BOB 8
#define MAX_Alice 125
#define MAX_Bob 159
#define MSG_BYTES 24
#define SECRETKEY_A_BYTES ((OALICE_BITS + 7) / 8)
#define SECRETKEY_B_BYTES ((OBOB_BITS - 1 + 7) / 8)
#define FP2_ENCODED_BYTES 2 * ((NBITS_FIELD + 7) / 8)
#ifdef COMPRESS
#define MASK2_BOB 0x03
#define MASK3_BOB 0xFF
#define ORDER_A_ENCODED_BYTES SECRETKEY_A_BYTES
#define ORDER_B_ENCODED_BYTES SECRETKEY_B_BYTES
#define COMPRESSED_CHUNK_CT (3 * ORDER_A_ENCODED_BYTES + FP2_ENCODED_BYTES + 2)
#define UNCOMPRESSEDPK_BYTES 378
// Table sizes used by the Entangled basis generation
#define TABLE_R_LEN 17
#define TABLE_V_LEN 34
// Parameters for discrete log computations
// Binary Pohlig-Hellman reduced to smaller logs of order ell^W
#define W_2 5
#define W_3 6
// ell^w
#define ELL2_W (1 << W_2)
#define ELL3_W 729
// ell^(e mod w)
#define ELL2_EMODW (1 << (OALICE_BITS % W_2))
#define ELL3_EMODW 27
// # of digits in the discrete log
#define DLEN_2 50 // ceil(eA/W_2)
#define DLEN_3 27 // ceil(eB/W_3)
// Length of the optimal strategy path for Pohlig-Hellman
#define PLEN_2 51
#define PLEN_3 28
#endif
// SIDH's basic element definitions and point representations
typedef digit_t felm_t[NWORDS_FIELD]; // Datatype for representing 503-bit field elements (512-bit max.)
typedef digit_t dfelm_t[2 * NWORDS_FIELD]; // Datatype for representing double-precision 2x503-bit field elements (2x512-bit max.)
typedef felm_t f2elm_t[2]; // Datatype for representing quadratic extension field elements GF(p503^2)
typedef struct {
f2elm_t X;
f2elm_t Z;
} point_proj; // Point representation in projective XZ Montgomery coordinates.
typedef point_proj point_proj_t[1];
#ifdef COMPRESS
typedef struct {
f2elm_t X;
f2elm_t Y;
f2elm_t Z;
} point_full_proj; // Point representation in full projective XYZ Montgomery coordinates
typedef point_full_proj point_full_proj_t[1];
typedef struct {
f2elm_t x;
f2elm_t y;
} point_affine; // Point representation in affine coordinates.
typedef point_affine point_t[1];
typedef f2elm_t publickey_t[3];
#endif
/**************** Function prototypes ****************/
/************* Multiprecision functions **************/
// Copy wordsize digits, c = a, where lng(a) = nwords
static void copy_words(const digit_t *a, digit_t *c, const unsigned int nwords);
// Multiprecision addition, c = a+b, where lng(a) = lng(b) = nwords. Returns the carry bit
static unsigned int mp_add(const digit_t *a, const digit_t *b, digit_t *c, const unsigned int nwords);
// 503-bit multiprecision addition, c = a+b
static void mp_add503(const digit_t *a, const digit_t *b, digit_t *c);
void oqs_kem_sike_mp_add503_asm(const digit_t *a, const digit_t *b, digit_t *c);
// Multiprecision subtraction, c = a-b, where lng(a) = lng(b) = nwords. Returns the borrow bit
static unsigned int mp_sub(const digit_t *a, const digit_t *b, digit_t *c, const unsigned int nwords);
// 2x503-bit multiprecision subtraction followed by addition with p503*2^512, c = a-b+(p503*2^512) if a-b < 0, otherwise c=a-b
void oqs_kem_sike_mp_subaddx2_asm(const digit_t *a, const digit_t *b, digit_t *c);
void oqs_kem_sike_mp_subadd503x2_asm(const digit_t *a, const digit_t *b, digit_t *c);
// Double 2x503-bit multiprecision subtraction, c = c-a-b, where c > a and c > b
void oqs_kem_sike_mp_dblsub503x2_asm(const digit_t *a, const digit_t *b, digit_t *c);
// Multiprecision left shift
static void mp_shiftleft(digit_t *x, unsigned int shift, const unsigned int nwords);
// Multiprecision right shift by one
static void mp_shiftr1(digit_t *x, const unsigned int nwords);
// Multiprecision left right shift by one
static void mp_shiftl1(digit_t *x, const unsigned int nwords);
// Digit multiplication, digit * digit -> 2-digit result
static void digit_x_digit(const digit_t a, const digit_t b, digit_t *c);
// Multiprecision comba multiply, c = a*b, where lng(a) = lng(b) = nwords.
static void mp_mul(const digit_t *a, const digit_t *b, digit_t *c, const unsigned int nwords);
/************ Field arithmetic functions *************/
// Copy of a field element, c = a
static void fpcopy503(const digit_t *a, digit_t *c);
// Zeroing a field element, a = 0
static void fpzero503(digit_t *a);
// Non constant-time comparison of two field elements. If a = b return TRUE, otherwise, return FALSE
static bool fpequal503_non_constant_time(const digit_t *a, const digit_t *b);
// Modular addition, c = a+b mod p503
extern void fpadd503(const digit_t *a, const digit_t *b, digit_t *c);
extern void oqs_kem_sike_fpadd503_asm(const digit_t *a, const digit_t *b, digit_t *c);
void oqs_kem_sike_fpadd503_inline_asm(const digit_t *a, const digit_t *b, const digit_t *p, digit_t *c);
// Modular subtraction, c = a-b mod p503
extern void fpsub503(const digit_t *a, const digit_t *b, digit_t *c);
extern void oqs_kem_sike_fpsub503_asm(const digit_t *a, const digit_t *b, digit_t *c);
void oqs_kem_sike_fpsub503_inline_asm(const digit_t *a, const digit_t *b, const digit_t *p, digit_t *c);
// Modular negation, a = -a mod p503
extern void fpneg503(digit_t *a);
// Modular division by two, c = a/2 mod p503.
static void fpdiv2_503(const digit_t *a, digit_t *c);
// Modular correction to reduce field element a in [0, 2*p503-1] to [0, p503-1].
static void fpcorrection503(digit_t *a);
// 503-bit Montgomery reduction, c = a mod p
static void rdc_mont(digit_t *a, digit_t *c);
void oqs_kem_sike_rdc503_asm(digit_t *ma, digit_t *mc);
// Field multiplication using Montgomery arithmetic, c = a*b*R^-1 mod p503, where R=2^768
static void fpmul503_mont(const digit_t *a, const digit_t *b, digit_t *c);
void oqs_kem_sike_mul503_asm(const digit_t *a, const digit_t *b, digit_t *c);
void oqs_kem_sike_mul503_inline_asm(const digit_t *a, const digit_t *b, digit_t *c);
// Field squaring using Montgomery arithmetic, c = a*b*R^-1 mod p503, where R=2^768
static void fpsqr503_mont(const digit_t *ma, digit_t *mc);
// Conversion to Montgomery representation
static void to_mont(const digit_t *a, digit_t *mc);
// Conversion from Montgomery representation to standard representation
static void from_mont(const digit_t *ma, digit_t *c);
// Field inversion, a = a^-1 in GF(p503)
static void fpinv503_mont(digit_t *a);
// Field inversion, a = a^-1 in GF(p503) using the binary GCD
static void fpinv503_mont_bingcd(digit_t *a);
// Chain to compute (p503-3)/4 using Montgomery arithmetic
static void fpinv503_chain_mont(digit_t *a);
/************ GF(p^2) arithmetic functions *************/
// Copy of a GF(p503^2) element, c = a
static void fp2copy503(const f2elm_t a, f2elm_t c);
// Zeroing a GF(p503^2) element, a = 0
static void fp2zero503(f2elm_t a);
// GF(p503^2) negation, a = -a in GF(p503^2)
static void fp2neg503(f2elm_t a);
// GF(p503^2) addition, c = a+b in GF(p503^2)
extern void fp2add503(const f2elm_t a, const f2elm_t b, f2elm_t c);
// GF(p503^2) subtraction, c = a-b in GF(p503^2)
extern void fp2sub503(const f2elm_t a, const f2elm_t b, f2elm_t c);
// GF(p503^2) division by two, c = a/2 in GF(p503^2)
static void fp2div2_503(const f2elm_t a, f2elm_t c);
// Modular correction, a = a in GF(p503^2)
static void fp2correction503(f2elm_t a);
// GF(p503^2) squaring using Montgomery arithmetic, c = a^2 in GF(p503^2)
static void fp2sqr503_mont(const f2elm_t a, f2elm_t c);
// GF(p503^2) multiplication using Montgomery arithmetic, c = a*b in GF(p503^2)
static void fp2mul503_mont(const f2elm_t a, const f2elm_t b, f2elm_t c);
// Conversion of a GF(p503^2) element to Montgomery representation
static void to_fp2mont(const f2elm_t a, f2elm_t mc);
// Conversion of a GF(p503^2) element from Montgomery representation to standard representation
static void from_fp2mont(const f2elm_t ma, f2elm_t c);
// GF(p503^2) inversion using Montgomery arithmetic, a = (a0-i*a1)/(a0^2+a1^2)
static void fp2inv503_mont(f2elm_t a);
// GF(p503^2) inversion, a = (a0-i*a1)/(a0^2+a1^2), GF(p503) inversion done using the binary GCD
static void fp2inv503_mont_bingcd(f2elm_t a);
// n-way Montgomery inversion
static void mont_n_way_inv(const f2elm_t *vec, const int n, f2elm_t *out);
/************ Elliptic curve and isogeny functions *************/
// Computes the j-invariant of a Montgomery curve with projective constant.
static void j_inv(const f2elm_t A, const f2elm_t C, f2elm_t jinv);
// Simultaneous doubling and differential addition.
static void xDBLADD(point_proj_t P, point_proj_t Q, const f2elm_t xPQ, const f2elm_t A24);
// Doubling of a Montgomery point in projective coordinates (X:Z).
static void xDBL(const point_proj_t P, point_proj_t Q, const f2elm_t A24plus, const f2elm_t C24);
// Computes [2^e](X:Z) on Montgomery curve with projective constant via e repeated doublings.
static void xDBLe(const point_proj_t P, point_proj_t Q, const f2elm_t A24plus, const f2elm_t C24, const int e);
// Differential addition.
static void xADD(point_proj_t P, const point_proj_t Q, const f2elm_t xPQ);
// Computes the corresponding 4-isogeny of a projective Montgomery point (X4:Z4) of order 4.
static void get_4_isog(const point_proj_t P, f2elm_t A24plus, f2elm_t C24, f2elm_t *coeff);
// Evaluates the isogeny at the point (X:Z) in the domain of the isogeny.
static void eval_4_isog(point_proj_t P, f2elm_t *coeff);
// Tripling of a Montgomery point in projective coordinates (X:Z).
static void xTPL(const point_proj_t P, point_proj_t Q, const f2elm_t A24minus, const f2elm_t A24plus);
// Computes [3^e](X:Z) on Montgomery curve with projective constant via e repeated triplings.
static void xTPLe(const point_proj_t P, point_proj_t Q, const f2elm_t A24minus, const f2elm_t A24plus, const int e);
// Computes the corresponding 3-isogeny of a projective Montgomery point (X3:Z3) of order 3.
static void get_3_isog(const point_proj_t P, f2elm_t A24minus, f2elm_t A24plus, f2elm_t *coeff);
// Computes the 3-isogeny R=phi(X:Z), given projective point (X3:Z3) of order 3 on a Montgomery curve and a point P with coefficients given in coeff.
static void eval_3_isog(point_proj_t Q, const f2elm_t *coeff);
// 3-way simultaneous inversion
static void inv_3_way(f2elm_t z1, f2elm_t z2, f2elm_t z3);
// Given the x-coordinates of P, Q, and R, returns the value A corresponding to the Montgomery curve E_A: y^2=x^3+A*x^2+x such that R=Q-P on E_A.
static void get_A(const f2elm_t xP, const f2elm_t xQ, const f2elm_t xR, f2elm_t A);
#endif
/********************************************************************************************
* SIDH: an efficient supersingular isogeny cryptography library
*
* Abstract: internal header file for P503
*********************************************************************************************/
#ifndef P503_INTERNAL_H
#define P503_INTERNAL_H
#include "../config.h"
#if (TARGET == TARGET_AMD64)
#define NWORDS_FIELD 8 // Number of words of a 503-bit field element
#define p503_ZERO_WORDS 3 // Number of "0" digits in the least significant part of p503 + 1
#elif (TARGET == TARGET_x86)
#define NWORDS_FIELD 16
#define p503_ZERO_WORDS 7
#elif (TARGET == TARGET_ARM)
#define NWORDS_FIELD 16
#define p503_ZERO_WORDS 7
#elif (TARGET == TARGET_ARM64)
#define NWORDS_FIELD 8
#define p503_ZERO_WORDS 3
#endif
// Basic constants
#define NBITS_FIELD 503
#define MAXBITS_FIELD 512
#define MAXWORDS_FIELD ((MAXBITS_FIELD + RADIX - 1) / RADIX) // Max. number of words to represent field elements
#define NWORDS64_FIELD ((NBITS_FIELD + 63) / 64) // Number of 64-bit words of a 503-bit field element
#define NBITS_ORDER 256
#define NWORDS_ORDER ((NBITS_ORDER + RADIX - 1) / RADIX) // Number of words of oA and oB, where oA and oB are the subgroup orders of Alice and Bob, resp.
#define NWORDS64_ORDER ((NBITS_ORDER + 63) / 64) // Number of 64-bit words of a 256-bit element
#define MAXBITS_ORDER NBITS_ORDER
#define ALICE 0
#define BOB 1
#define OALICE_BITS 250
#define OBOB_BITS 253
#define OBOB_EXPON 159
#define MASK_ALICE 0x03
#define MASK_BOB 0x0F
#define PRIME p503
#define PARAM_A 6
#define PARAM_C 1
// Fixed parameters for isogeny tree computation
#define MAX_INT_POINTS_ALICE 7
#define MAX_INT_POINTS_BOB 8
#define MAX_Alice 125
#define MAX_Bob 159
#define MSG_BYTES 24
#define SECRETKEY_A_BYTES ((OALICE_BITS + 7) / 8)
#define SECRETKEY_B_BYTES ((OBOB_BITS - 1 + 7) / 8)
#define FP2_ENCODED_BYTES 2 * ((NBITS_FIELD + 7) / 8)
#ifdef COMPRESS
#define MASK2_BOB 0x03
#define MASK3_BOB 0xFF
#define ORDER_A_ENCODED_BYTES SECRETKEY_A_BYTES
#define ORDER_B_ENCODED_BYTES SECRETKEY_B_BYTES
#define COMPRESSED_CHUNK_CT (3 * ORDER_A_ENCODED_BYTES + FP2_ENCODED_BYTES + 2)
#define UNCOMPRESSEDPK_BYTES 378
// Table sizes used by the Entangled basis generation
#define TABLE_R_LEN 17
#define TABLE_V_LEN 34
// Parameters for discrete log computations
// Binary Pohlig-Hellman reduced to smaller logs of order ell^W
#define W_2 5
#define W_3 6
// ell^w
#define ELL2_W (1 << W_2)
#define ELL3_W 729
// ell^(e mod w)
#define ELL2_EMODW (1 << (OALICE_BITS % W_2))
#define ELL3_EMODW 27
// # of digits in the discrete log
#define DLEN_2 50 // ceil(eA/W_2)
#define DLEN_3 27 // ceil(eB/W_3)
// Length of the optimal strategy path for Pohlig-Hellman
#define PLEN_2 51
#define PLEN_3 28
#endif
// SIDH's basic element definitions and point representations
typedef digit_t felm_t[NWORDS_FIELD]; // Datatype for representing 503-bit field elements (512-bit max.)
typedef digit_t dfelm_t[2 * NWORDS_FIELD]; // Datatype for representing double-precision 2x503-bit field elements (2x512-bit max.)
typedef felm_t f2elm_t[2]; // Datatype for representing quadratic extension field elements GF(p503^2)
typedef struct {
f2elm_t X;
f2elm_t Z;
} point_proj; // Point representation in projective XZ Montgomery coordinates.
typedef point_proj point_proj_t[1];
#ifdef COMPRESS
typedef struct {
f2elm_t X;
f2elm_t Y;
f2elm_t Z;
} point_full_proj; // Point representation in full projective XYZ Montgomery coordinates
typedef point_full_proj point_full_proj_t[1];
typedef struct {
f2elm_t x;
f2elm_t y;
} point_affine; // Point representation in affine coordinates.
typedef point_affine point_t[1];
typedef f2elm_t publickey_t[3];
#endif
/**************** Function prototypes ****************/
/************* Multiprecision functions **************/
// Copy wordsize digits, c = a, where lng(a) = nwords
static void copy_words(const digit_t *a, digit_t *c, const unsigned int nwords);
// Multiprecision addition, c = a+b, where lng(a) = lng(b) = nwords. Returns the carry bit
static unsigned int mp_add(const digit_t *a, const digit_t *b, digit_t *c, const unsigned int nwords);
// 503-bit multiprecision addition, c = a+b
static void mp_add503(const digit_t *a, const digit_t *b, digit_t *c);
void oqs_kem_sike_mp_add503_asm(const digit_t *a, const digit_t *b, digit_t *c);
// Multiprecision subtraction, c = a-b, where lng(a) = lng(b) = nwords. Returns the borrow bit
static unsigned int mp_sub(const digit_t *a, const digit_t *b, digit_t *c, const unsigned int nwords);
// 2x503-bit multiprecision subtraction followed by addition with p503*2^512, c = a-b+(p503*2^512) if a-b < 0, otherwise c=a-b
void oqs_kem_sike_mp_subaddx2_asm(const digit_t *a, const digit_t *b, digit_t *c);
void oqs_kem_sike_mp_subadd503x2_asm(const digit_t *a, const digit_t *b, digit_t *c);
// Double 2x503-bit multiprecision subtraction, c = c-a-b, where c > a and c > b
void oqs_kem_sike_mp_dblsub503x2_asm(const digit_t *a, const digit_t *b, digit_t *c);
// Multiprecision left shift
static void mp_shiftleft(digit_t *x, unsigned int shift, const unsigned int nwords);
// Multiprecision right shift by one
static void mp_shiftr1(digit_t *x, const unsigned int nwords);
// Multiprecision left right shift by one
static void mp_shiftl1(digit_t *x, const unsigned int nwords);
// Digit multiplication, digit * digit -> 2-digit result
static void digit_x_digit(const digit_t a, const digit_t b, digit_t *c);
// Multiprecision comba multiply, c = a*b, where lng(a) = lng(b) = nwords.
static void mp_mul(const digit_t *a, const digit_t *b, digit_t *c, const unsigned int nwords);
/************ Field arithmetic functions *************/
// Copy of a field element, c = a
static void fpcopy503(const digit_t *a, digit_t *c);
// Zeroing a field element, a = 0
static void fpzero503(digit_t *a);
// Non constant-time comparison of two field elements. If a = b return TRUE, otherwise, return FALSE
static bool fpequal503_non_constant_time(const digit_t *a, const digit_t *b);
// Modular addition, c = a+b mod p503
extern void fpadd503(const digit_t *a, const digit_t *b, digit_t *c);
extern void oqs_kem_sike_fpadd503_asm(const digit_t *a, const digit_t *b, digit_t *c);
void oqs_kem_sike_fpadd503_inline_asm(const digit_t *a, const digit_t *b, const digit_t *p, digit_t *c);
// Modular subtraction, c = a-b mod p503
extern void fpsub503(const digit_t *a, const digit_t *b, digit_t *c);
extern void oqs_kem_sike_fpsub503_asm(const digit_t *a, const digit_t *b, digit_t *c);
void oqs_kem_sike_fpsub503_inline_asm(const digit_t *a, const digit_t *b, const digit_t *p, digit_t *c);
// Modular negation, a = -a mod p503
extern void fpneg503(digit_t *a);
// Modular division by two, c = a/2 mod p503.
static void fpdiv2_503(const digit_t *a, digit_t *c);
// Modular correction to reduce field element a in [0, 2*p503-1] to [0, p503-1].
static void fpcorrection503(digit_t *a);
// 503-bit Montgomery reduction, c = a mod p
static void rdc_mont(digit_t *a, digit_t *c);
void oqs_kem_sike_rdc503_asm(digit_t *ma, digit_t *mc);
// Field multiplication using Montgomery arithmetic, c = a*b*R^-1 mod p503, where R=2^768
static void fpmul503_mont(const digit_t *a, const digit_t *b, digit_t *c);
void oqs_kem_sike_mul503_asm(const digit_t *a, const digit_t *b, digit_t *c);
void oqs_kem_sike_mul503_inline_asm(const digit_t *a, const digit_t *b, digit_t *c);
// Field squaring using Montgomery arithmetic, c = a*b*R^-1 mod p503, where R=2^768
static void fpsqr503_mont(const digit_t *ma, digit_t *mc);
// Conversion to Montgomery representation
static void to_mont(const digit_t *a, digit_t *mc);
// Conversion from Montgomery representation to standard representation
static void from_mont(const digit_t *ma, digit_t *c);
// Field inversion, a = a^-1 in GF(p503)
static void fpinv503_mont(digit_t *a);
// Field inversion, a = a^-1 in GF(p503) using the binary GCD
static void fpinv503_mont_bingcd(digit_t *a);
// Chain to compute (p503-3)/4 using Montgomery arithmetic
static void fpinv503_chain_mont(digit_t *a);
/************ GF(p^2) arithmetic functions *************/
// Copy of a GF(p503^2) element, c = a
static void fp2copy503(const f2elm_t a, f2elm_t c);
// Zeroing a GF(p503^2) element, a = 0
static void fp2zero503(f2elm_t a);
// GF(p503^2) negation, a = -a in GF(p503^2)
static void fp2neg503(f2elm_t a);
// GF(p503^2) addition, c = a+b in GF(p503^2)
extern void fp2add503(const f2elm_t a, const f2elm_t b, f2elm_t c);
// GF(p503^2) subtraction, c = a-b in GF(p503^2)
extern void fp2sub503(const f2elm_t a, const f2elm_t b, f2elm_t c);
// GF(p503^2) division by two, c = a/2 in GF(p503^2)
static void fp2div2_503(const f2elm_t a, f2elm_t c);
// Modular correction, a = a in GF(p503^2)
static void fp2correction503(f2elm_t a);
// GF(p503^2) squaring using Montgomery arithmetic, c = a^2 in GF(p503^2)
static void fp2sqr503_mont(const f2elm_t a, f2elm_t c);
// GF(p503^2) multiplication using Montgomery arithmetic, c = a*b in GF(p503^2)
static void fp2mul503_mont(const f2elm_t a, const f2elm_t b, f2elm_t c);
// Conversion of a GF(p503^2) element to Montgomery representation
static void to_fp2mont(const f2elm_t a, f2elm_t mc);
// Conversion of a GF(p503^2) element from Montgomery representation to standard representation
static void from_fp2mont(const f2elm_t ma, f2elm_t c);
// GF(p503^2) inversion using Montgomery arithmetic, a = (a0-i*a1)/(a0^2+a1^2)
static void fp2inv503_mont(f2elm_t a);
// GF(p503^2) inversion, a = (a0-i*a1)/(a0^2+a1^2), GF(p503) inversion done using the binary GCD
static void fp2inv503_mont_bingcd(f2elm_t a);
// n-way Montgomery inversion
static void mont_n_way_inv(const f2elm_t *vec, const int n, f2elm_t *out);
/************ Elliptic curve and isogeny functions *************/
// Computes the j-invariant of a Montgomery curve with projective constant.
static void j_inv(const f2elm_t A, const f2elm_t C, f2elm_t jinv);
// Simultaneous doubling and differential addition.
static void xDBLADD(point_proj_t P, point_proj_t Q, const f2elm_t xPQ, const f2elm_t A24);
// Doubling of a Montgomery point in projective coordinates (X:Z).
static void xDBL(const point_proj_t P, point_proj_t Q, const f2elm_t A24plus, const f2elm_t C24);
// Computes [2^e](X:Z) on Montgomery curve with projective constant via e repeated doublings.
static void xDBLe(const point_proj_t P, point_proj_t Q, const f2elm_t A24plus, const f2elm_t C24, const int e);
// Differential addition.
static void xADD(point_proj_t P, const point_proj_t Q, const f2elm_t xPQ);
// Computes the corresponding 4-isogeny of a projective Montgomery point (X4:Z4) of order 4.
static void get_4_isog(const point_proj_t P, f2elm_t A24plus, f2elm_t C24, f2elm_t *coeff);
// Evaluates the isogeny at the point (X:Z) in the domain of the isogeny.
static void eval_4_isog(point_proj_t P, f2elm_t *coeff);
// Tripling of a Montgomery point in projective coordinates (X:Z).
static void xTPL(const point_proj_t P, point_proj_t Q, const f2elm_t A24minus, const f2elm_t A24plus);
// Computes [3^e](X:Z) on Montgomery curve with projective constant via e repeated triplings.
static void xTPLe(const point_proj_t P, point_proj_t Q, const f2elm_t A24minus, const f2elm_t A24plus, const int e);
// Computes the corresponding 3-isogeny of a projective Montgomery point (X3:Z3) of order 3.
static void get_3_isog(const point_proj_t P, f2elm_t A24minus, f2elm_t A24plus, f2elm_t *coeff);
// Computes the 3-isogeny R=phi(X:Z), given projective point (X3:Z3) of order 3 on a Montgomery curve and a point P with coefficients given in coeff.
static void eval_3_isog(point_proj_t Q, const f2elm_t *coeff);
// 3-way simultaneous inversion
static void inv_3_way(f2elm_t z1, f2elm_t z2, f2elm_t z3);
// Given the x-coordinates of P, Q, and R, returns the value A corresponding to the Montgomery curve E_A: y^2=x^3+A*x^2+x such that R=Q-P on E_A.
static void get_A(const f2elm_t xP, const f2elm_t xQ, const f2elm_t xR, f2elm_t A);
#endif

View File

@ -14,8 +14,8 @@ extern const uint64_t p610x2[NWORDS_FIELD];
*/
__inline void fpadd610(const digit_t *a, const digit_t *b, digit_t *c) { // Modular addition, c = a+b mod p610.
// Inputs: a, b in [0, 2*p610-1]
// Output: c in [0, 2*p610-1]
// Inputs: a, b in [0, 2*p610-1]
// Output: c in [0, 2*p610-1]
#if (OS_TARGET == OS_WIN || OS_TARGET == OS_DARWIN)
unsigned int i, carry = 0;
@ -44,8 +44,8 @@ __inline void fpadd610(const digit_t *a, const digit_t *b, digit_t *c) { // Modu
}
__inline void fpsub610(const digit_t *a, const digit_t *b, digit_t *c) { // Modular subtraction, c = a-b mod p610.
// Inputs: a, b in [0, 2*p610-1]
// Output: c in [0, 2*p610-1]
// Inputs: a, b in [0, 2*p610-1]
// Output: c in [0, 2*p610-1]
#if (OS_TARGET == OS_WIN || OS_TARGET == OS_DARWIN)
unsigned int i, borrow = 0;
@ -69,7 +69,7 @@ __inline void fpsub610(const digit_t *a, const digit_t *b, digit_t *c) { // Modu
}
__inline void fpneg610(digit_t *a) { // Modular negation, a = -a mod p610.
// Input/output: a in [0, 2*p610-1]
// Input/output: a in [0, 2*p610-1]
unsigned int i, borrow = 0;
for (i = 0; i < NWORDS_FIELD; i++) {
@ -78,8 +78,8 @@ __inline void fpneg610(digit_t *a) { // Modular negation, a = -a mod p610.
}
void fpdiv2_610(const digit_t *a, digit_t *c) { // Modular division by two, c = a/2 mod p610.
// Input : a in [0, 2*p610-1]
// Output: c in [0, 2*p610-1]
// Input : a in [0, 2*p610-1]
// Output: c in [0, 2*p610-1]
unsigned int i, carry = 0;
digit_t mask;
@ -414,9 +414,9 @@ void mp_mul(const digit_t *a, const digit_t *b, digit_t *c, const unsigned int n
}
void rdc_mont(digit_t *ma, digit_t *mc) { // Montgomery reduction exploiting special form of the prime.
// mc = ma*R^-1 mod p610x2, where R = 2^640.
// If ma < 2^640*p610, the output mc is in the range [0, 2*p610-1].
// ma is assumed to be in Montgomery representation.
// mc = ma*R^-1 mod p610x2, where R = 2^640.
// If ma < 2^640*p610, the output mc is in the range [0, 2*p610-1].
// ma is assumed to be in Montgomery representation.
#if (OS_TARGET == OS_WIN || OS_TARGET == OS_DARWIN)
unsigned int carry;

View File

@ -32,11 +32,14 @@
//
const uint64_t p610[NWORDS64_FIELD] = {0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x6E01FFFFFFFFFFFF,
0xB1784DE8AA5AB02E, 0x9AE7BF45048FF9AB, 0xB255B2FA10C4252A, 0x819010C251E7D88C, 0x000000027BF6A768};
0xB1784DE8AA5AB02E, 0x9AE7BF45048FF9AB, 0xB255B2FA10C4252A, 0x819010C251E7D88C, 0x000000027BF6A768
};
const uint64_t p610p1[NWORDS64_FIELD] = {0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x6E02000000000000,
0xB1784DE8AA5AB02E, 0x9AE7BF45048FF9AB, 0xB255B2FA10C4252A, 0x819010C251E7D88C, 0x000000027BF6A768};
0xB1784DE8AA5AB02E, 0x9AE7BF45048FF9AB, 0xB255B2FA10C4252A, 0x819010C251E7D88C, 0x000000027BF6A768
};
const uint64_t p610x2[NWORDS64_FIELD] = {0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xDC03FFFFFFFFFFFF,
0x62F09BD154B5605C, 0x35CF7E8A091FF357, 0x64AB65F421884A55, 0x03202184A3CFB119, 0x00000004F7ED4ED1};
0x62F09BD154B5605C, 0x35CF7E8A091FF357, 0x64AB65F421884A55, 0x03202184A3CFB119, 0x00000004F7ED4ED1
};
// Order of Alice's subgroup
static const uint64_t Alice_order[NWORDS64_ORDER] = {0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0002000000000000};
// Order of Bob's subgroup
@ -53,7 +56,8 @@ static const uint64_t A_gen[6 * NWORDS64_FIELD] = {0x5019EC96A75AC57A, 0x8AEA0E7
0x261DD0782CEC958D, 0xC25B3AE64BBC0311, 0x9F21B8A8981B15FE, 0xA3C0B52CD5FFC45B, 0x5D2E65A016702C6A,
0x8C5586CA98722EDE, 0x61490A967A6B4B1A, 0xFA64E30231F719AF, 0x9CEAB8B6301BB2DF, 0x00000000CF5AEA7D, // XRA0
0xB980435A77B912C0, 0x2B4A97F70E0FC873, 0x415C7FA4DE96F43C, 0xE5EED95643E443FD, 0xCBE18DB57C51B354,
0x51C96C3FFABD2D46, 0x5C14637B9A5765D6, 0x45D2369C4D0199A5, 0x25A1F9C5BBF1E683, 0x000000025AD7A11B}; // XRA1
0x51C96C3FFABD2D46, 0x5C14637B9A5765D6, 0x45D2369C4D0199A5, 0x25A1F9C5BBF1E683, 0x000000025AD7A11B
}; // XRA1
// Bob's generator values {XPB0, XQB0, XRB0 + XRB1*i} in GF(p610^2), expressed in Montgomery representation
static const uint64_t B_gen[6 * NWORDS64_FIELD] = {0xC6C8E180E41884BA, 0x2161D2F4FBC32B95, 0xCBF83091BDB34092, 0xD742CC0AD4CC7E38, 0x61A1FA7E1B14FBD7,
0xF0E5FC70137597C4, 0x1F0C8F2585E20B1F, 0xC68E44A1C032A4C2, 0xE3C65FB8AF155A0D, 0x00000001409EE8D5, // XPB0
@ -66,32 +70,37 @@ static const uint64_t B_gen[6 * NWORDS64_FIELD] = {0xC6C8E180E41884BA, 0x2161D2F
0x7A87897A0C4C3FD7, 0x3C1879ECD4D33D76, 0x595C28A36FFBA1A0, 0xF53FF66A2A7FD0FB, 0xB39F5A91230E56FA,
0x81F21610DA3EA8B5, 0xEBB3B9A627428A90, 0x8661123B35748010, 0xE196173B9C48781D, 0x00000002198166AC, // XRB0
0x5E3CC79B37006D6A, 0xE0358A9AB2EA7923, 0x3B725CB595180951, 0x0724637F1DD0C191, 0x7BB031B67DAB9D19,
0x53CCB8BECEDD3435, 0xEE5DF7FFEBFA7A0A, 0x899EDB7D8B9694C4, 0x0CA38EB4AE5506B6, 0x00000001489DE1CD}; // XRB1
0x53CCB8BECEDD3435, 0xEE5DF7FFEBFA7A0A, 0x899EDB7D8B9694C4, 0x0CA38EB4AE5506B6, 0x00000001489DE1CD
}; // XRB1
// Montgomery constant Montgomery_R2 = (2^640)^2 mod p610
static const uint64_t Montgomery_R2[NWORDS64_FIELD] = {0xE75F5D201A197727, 0xE0B85963B627392E, 0x6BC1707818DE493D, 0xDC7F419940D1A0C5, 0x7358030979EDE54A,
0x84F4BEBDEED75A5C, 0x7ECCA66E13427B47, 0xC5BB4E65280080B3, 0x7019950F516DA19A, 0x000000008E290FF3};
0x84F4BEBDEED75A5C, 0x7ECCA66E13427B47, 0xC5BB4E65280080B3, 0x7019950F516DA19A, 0x000000008E290FF3
};
// Value one in Montgomery representation
static const uint64_t Montgomery_one[NWORDS64_FIELD] = {0x00000000670CC8E6, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x9A34000000000000,
0x4D99C2BD28717A3F, 0x0A4A1839A323D41C, 0xD2B62215D06AD1E2, 0x1369026E862CAF3D, 0x000000010894E964};
0x4D99C2BD28717A3F, 0x0A4A1839A323D41C, 0xD2B62215D06AD1E2, 0x1369026E862CAF3D, 0x000000010894E964
};
// Fixed parameters for isogeny tree computation
static const unsigned int strat_Alice[MAX_Alice - 1] = {
67, 37, 21, 12, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 5, 3, 2, 1, 1, 1, 1,
2, 1, 1, 1, 9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, 16, 9,
5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1,
1, 4, 2, 1, 1, 2, 1, 1, 33, 16, 8, 5, 2, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 2, 1,
1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 16, 8, 4, 2, 1, 1, 1, 2, 1, 1,
4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1};
67, 37, 21, 12, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 5, 3, 2, 1, 1, 1, 1,
2, 1, 1, 1, 9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, 16, 9,
5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1,
1, 4, 2, 1, 1, 2, 1, 1, 33, 16, 8, 5, 2, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 2, 1,
1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 16, 8, 4, 2, 1, 1, 1, 2, 1, 1,
4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1
};
static const unsigned int strat_Bob[MAX_Bob - 1] = {
86, 48, 27, 15, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 7, 4, 2, 1, 1, 2, 1,
1, 3, 2, 1, 1, 1, 1, 12, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 5, 3, 2, 1, 1,
1, 1, 2, 1, 1, 1, 21, 12, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 5, 3, 2, 1, 1,
1, 1, 2, 1, 1, 1, 9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, 38,
21, 12, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1,
9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, 17, 9, 5, 3, 2, 1, 1,
1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2,
1, 1};
86, 48, 27, 15, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 7, 4, 2, 1, 1, 2, 1,
1, 3, 2, 1, 1, 1, 1, 12, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 5, 3, 2, 1, 1,
1, 1, 2, 1, 1, 1, 21, 12, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 5, 3, 2, 1, 1,
1, 1, 2, 1, 1, 1, 9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, 38,
21, 12, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1,
9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, 17, 9, 5, 3, 2, 1, 1,
1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2,
1, 1
};
// Setting up macro defines and including GF(p), GF(p^2), curve, isogeny and kex functions
#define fpcopy fpcopy610

View File

@ -33,11 +33,14 @@
//
static const uint64_t p610[NWORDS64_FIELD] = {0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x6E01FFFFFFFFFFFF,
0xB1784DE8AA5AB02E, 0x9AE7BF45048FF9AB, 0xB255B2FA10C4252A, 0x819010C251E7D88C, 0x000000027BF6A768};
0xB1784DE8AA5AB02E, 0x9AE7BF45048FF9AB, 0xB255B2FA10C4252A, 0x819010C251E7D88C, 0x000000027BF6A768
};
static const uint64_t p610p1[NWORDS64_FIELD] = {0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x6E02000000000000,
0xB1784DE8AA5AB02E, 0x9AE7BF45048FF9AB, 0xB255B2FA10C4252A, 0x819010C251E7D88C, 0x000000027BF6A768};
0xB1784DE8AA5AB02E, 0x9AE7BF45048FF9AB, 0xB255B2FA10C4252A, 0x819010C251E7D88C, 0x000000027BF6A768
};
static const uint64_t p610x2[NWORDS64_FIELD] = {0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xDC03FFFFFFFFFFFF,
0x62F09BD154B5605C, 0x35CF7E8A091FF357, 0x64AB65F421884A55, 0x03202184A3CFB119, 0x00000004F7ED4ED1};
0x62F09BD154B5605C, 0x35CF7E8A091FF357, 0x64AB65F421884A55, 0x03202184A3CFB119, 0x00000004F7ED4ED1
};
// Order of Alice's subgroup
static const uint64_t Alice_order[NWORDS64_ORDER] = {0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0002000000000000};
// Order of Bob's subgroup
@ -55,7 +58,8 @@ static const uint64_t A_gen[6 * NWORDS64_FIELD] = {0x31C8AF7FFC0DE9FA, 0x8A8AD55
0x38687702D78D1A93, 0x58C09FD23B1E1B56, 0xC54917327D5C0FAB, 0xB6D55B7BE801A3C, 0xEB3AE21C8B93E9E9,
0xECB45AD6D24FF76A, 0x850645B4F39EC5F2, 0xE6F78202586C9B3A, 0x2923209A250F7F66, 0x26FB150F, // XRA0
0x5AC7B27F9096F718, 0x487DDD2820132C83, 0x6B21AC48569E12D8, 0x57B54E5A827D1CD9, 0xDB7C4BEB143E4130,
0xB6781CA1DA245EAD, 0xCC09878A2A6D7C45, 0x980726C5232C75E5, 0x50D3A7350792C35F, 0x172B595DB}; // XRA1
0xB6781CA1DA245EAD, 0xCC09878A2A6D7C45, 0x980726C5232C75E5, 0x50D3A7350792C35F, 0x172B595DB
}; // XRA1
/* Basis for Bob on A = 6, expressed in Montgomery representation */
static const uint64_t B_gen[6 * NWORDS64_FIELD] = {0xD4A2CF040BC56F2C, 0x58F1D1D2B190EDE7, 0x2229F10D3BC7BA47, 0x769AB0F0EDD86AA4, 0x97F1214B80D8463,
@ -68,13 +72,15 @@ static const uint64_t B_gen[6 * NWORDS64_FIELD] = {0xD4A2CF040BC56F2C, 0x58F1D1D
0x88B72428E4D5F16C, 0x5215D742081BE0DC, 0xA0620DB14AE42733, 0xA68175C8C4B68925, 0x62651A3C, // XQB1
0x4F62205A5DAFB369, 0xA2B75D5BC06C691F, 0x6B82C9B893D51C38, 0x2C2467D7AB7DAA2C, 0x8A8D5AC13C2C5ADD,
0xBC3AEC544F8953F5, 0xBC43C1BE1B1DC069, 0xB8CDA0908AEBCD84, 0xA213356DB0FBFCFF, 0x15F063030, // XRB0
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; // XRB1
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
}; // XRB1
/* The x-coordinate of lB^(eB-1)*QB, expressed in Montgomery representation */
static const uint64_t XQB3[2 * NWORDS64_FIELD] = {0x4E8DA387C42D31D0, 0x83AFE0DEB4FCE84B, 0xE819FEA7B6AE32CB, 0xA3DA371FFE9EE0F2, 0x4765959DBFECDE2D,
0xDB446F20746721E0, 0xE2596FFE42E2D7A8, 0x1FC46DF0BC2B8759, 0x9F5106F3AD0A27F8, 0x161083808,
0xA88E809BEF28310C, 0x506DB48241A76019, 0xE9FB9219833DF071, 0x342D697582036AEE, 0x25F078F10F357AFB,
0x43CE96BEE1668B06, 0xC540E958A6494D2, 0x46EB300B952B437D, 0x898338D77E9F811D, 0x1FC9961CB};
0x43CE96BEE1668B06, 0xC540E958A6494D2, 0x46EB300B952B437D, 0x898338D77E9F811D, 0x1FC9961CB
};
static const uint64_t A_basis_zero[8 * NWORDS64_FIELD] = {0x31C8AF80CA277BC7, 0x8A8AD55D2AC8A709, 0x95A4DC49B64E5B2C, 0xF08C77AAE90ABE83, 0x2DC44FF97C95845D,
0xE25D5D22CB0C4641, 0xEDA1E4D340EC56D7, 0x2AE81B9DCDAA0FF1, 0xB4292D8E409BC484, 0x1D5B8282A,
@ -91,7 +97,8 @@ static const uint64_t A_basis_zero[8 * NWORDS64_FIELD] = {0x31C8AF80CA277BC7, 0x
0x59DD6DAF69D05BED, 0xD76AC76FF586B73A, 0x7FE9D57BA40A785A, 0xD14A8A25B5B1A187, 0xA96A1F6746EC4DCB,
0x3D12E7FA86078B0A, 0x37816E342D89C86B, 0xEF93BD5D8E68FE5, 0x582A083E04E4D83D, 0x1A402EB75,
0x439B3817B316DC12, 0xAAC33FB9DB2CFE99, 0x103161162202C633, 0x3C38BFDA7559D6F5, 0xB4BC209633AB8D22,
0xA1724B6332EFE4FE, 0x81919EE777E6B9E1, 0xD15DFC6FAB242CF4, 0xD69C41AF15E2B7FC, 0x274D72579};
0xA1724B6332EFE4FE, 0x81919EE777E6B9E1, 0xD15DFC6FAB242CF4, 0xD69C41AF15E2B7FC, 0x274D72579
};
/* Basis for Bob on A = 0, expressed in Montgomery representation */
static const uint64_t B_basis_zero[8 * NWORDS64_FIELD] = {0x203596CF0245B227, 0xFE7D4CB978F11517, 0xEC79574E9D7DD13A, 0xD24627B69D4DFF63, 0x85B4D3B2B5426BBF,
@ -105,7 +112,8 @@ static const uint64_t B_basis_zero[8 * NWORDS64_FIELD] = {0x203596CF0245B227, 0x
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0xDFE1CAFF47350FFB, 0x7F6641B5806DBD07, 0xD558CE2B43292C47, 0x28EB4A4147C77BD6, 0x143218EB29F5FB6C,
0x5F457BD167A2260F, 0x26D9639E9DD4A15D, 0xEC9DFA3764433777, 0x9D8C59E2D257CACF, 0x1D2D65779};
0x5F457BD167A2260F, 0x26D9639E9DD4A15D, 0xEC9DFA3764433777, 0x9D8C59E2D257CACF, 0x1D2D65779
};
/* Full 3-torsion for Bob on A = 0, expressed in Montgomery representation */
static const uint64_t B_gen_3_tors[16 * NWORDS64_FIELD] = {0x1930B476A230B7BE, 0x3A42EE16DC949E2, 0x838416CC861CB74D, 0xE43303F18BFF483E, 0x30C6C49AC1829C11,
@ -133,16 +141,19 @@ static const uint64_t B_gen_3_tors[16 * NWORDS64_FIELD] = {0x1930B476A230B7BE, 0
0xC41ECDCAECF46668, 0x3303A35DC32C0272, 0x6A10EEBB3E7C798D, 0x800B26C6B6F0F2B7, 0xE0AA44F811ECA6C6,
0x38BB298B83C41423, 0x5C8E988E2C1B6909, 0xD61B6FE6260A9672, 0xE249E98EF30D4401, 0xA91ADF39,
0xC41ECDCAECF46668, 0x3303A35DC32C0272, 0x6A10EEBB3E7C798D, 0x800B26C6B6F0F2B7, 0xE0AA44F811ECA6C6,
0x38BB298B83C41423, 0x5C8E988E2C1B6909, 0xD61B6FE6260A9672, 0xE249E98EF30D4401, 0xA91ADF39};
0x38BB298B83C41423, 0x5C8E988E2C1B6909, 0xD61B6FE6260A9672, 0xE249E98EF30D4401, 0xA91ADF39
};
/* Pre-computed pairing ReducedTatePairing(R0,S3,lB^eB) on A = 0 */
static const uint64_t g_R_S_im[NWORDS64_FIELD] = {0x58B92E3BB6DC9E31, 0x3E280F90A5818BDA, 0x8BF300AC24A8E69A, 0x2E12E47000B08F86, 0xB01B3531200990E9,
0xF63C539B47B5A4FE, 0x9F70EF0C3FFAB9BA, 0xCFBD59EBE2438F9B, 0x1E7E8AD9F5361552, 0xC2DDA200};
0xF63C539B47B5A4FE, 0x9F70EF0C3FFAB9BA, 0xCFBD59EBE2438F9B, 0x1E7E8AD9F5361552, 0xC2DDA200
};
static const uint64_t Montgomery_R[NWORDS64_FIELD] = {0};
// Montgomery constant Montgomery_R2 = (2^640)^2 mod p610
static const uint64_t Montgomery_R2[NWORDS64_FIELD] = {0xE75F5D201A197727, 0xE0B85963B627392E, 0x6BC1707818DE493D, 0xDC7F419940D1A0C5, 0x7358030979EDE54A,
0x84F4BEBDEED75A5C, 0x7ECCA66E13427B47, 0xC5BB4E65280080B3, 0x7019950F516DA19A, 0x000000008E290FF3};
0x84F4BEBDEED75A5C, 0x7ECCA66E13427B47, 0xC5BB4E65280080B3, 0x7019950F516DA19A, 0x000000008E290FF3
};
// constant Montgomery_RB1 = (2^NBITS_ORDER)^2 mod Bob_order
static const uint64_t Montgomery_RB1[NWORDS64_FIELD] = {0x4FDA7CB300F00BFB, 0x8559FEAD08AF7CE1, 0x6C728679071D8D77, 0xFBFABAAF1825440F, 0x8D0536062AB9};
@ -152,41 +163,47 @@ static const uint64_t Montgomery_RB2[NWORDS64_FIELD] = {0x5BAEA880514636FF, 0x32
// Value one in Montgomery representation
static const uint64_t Montgomery_one[NWORDS64_FIELD] = {0x00000000670CC8E6, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x9A34000000000000,
0x4D99C2BD28717A3F, 0x0A4A1839A323D41C, 0xD2B62215D06AD1E2, 0x1369026E862CAF3D, 0x000000010894E964};
0x4D99C2BD28717A3F, 0x0A4A1839A323D41C, 0xD2B62215D06AD1E2, 0x1369026E862CAF3D, 0x000000010894E964
};
// 1/3 mod p
static const uint64_t threeinv[NWORDS64_FIELD] = {
0x5555555577AEEDA2, 0x5555555555555555, 0x5555555555555555, 0x5555555555555555, 0xDE11555555555555, 0xC488963F0D7B28BF, 0xAE18B2BDE10BF15E, 0x463CB6074578F0A0, 0x5BCDAB7A2CB98FBF, 0x5831A321};
0x5555555577AEEDA2, 0x5555555555555555, 0x5555555555555555, 0x5555555555555555, 0xDE11555555555555, 0xC488963F0D7B28BF, 0xAE18B2BDE10BF15E, 0x463CB6074578F0A0, 0x5BCDAB7A2CB98FBF, 0x5831A321
};
// Fixed parameters for isogeny tree computation
static const unsigned int strat_Alice[MAX_Alice - 1] = {
67, 37, 21, 12, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 5, 3, 2, 1, 1, 1, 1,
2, 1, 1, 1, 9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, 16, 9,
5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1,
1, 4, 2, 1, 1, 2, 1, 1, 33, 16, 8, 5, 2, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 2, 1,
1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 16, 8, 4, 2, 1, 1, 1, 2, 1, 1,
4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1};
67, 37, 21, 12, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 5, 3, 2, 1, 1, 1, 1,
2, 1, 1, 1, 9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, 16, 9,
5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1,
1, 4, 2, 1, 1, 2, 1, 1, 33, 16, 8, 5, 2, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 2, 1,
1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 16, 8, 4, 2, 1, 1, 1, 2, 1, 1,
4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1
};
static const unsigned int strat_Bob[MAX_Bob - 1] = {
86, 48, 27, 15, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 7, 4, 2, 1, 1, 2, 1,
1, 3, 2, 1, 1, 1, 1, 12, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 5, 3, 2, 1, 1,
1, 1, 2, 1, 1, 1, 21, 12, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 5, 3, 2, 1, 1,
1, 1, 2, 1, 1, 1, 9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, 38,
21, 12, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1,
9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, 17, 9, 5, 3, 2, 1, 1,
1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2,
1, 1};
86, 48, 27, 15, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 7, 4, 2, 1, 1, 2, 1,
1, 3, 2, 1, 1, 1, 1, 12, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 5, 3, 2, 1, 1,
1, 1, 2, 1, 1, 1, 21, 12, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 5, 3, 2, 1, 1,
1, 1, 2, 1, 1, 1, 9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, 38,
21, 12, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1,
9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, 17, 9, 5, 3, 2, 1, 1,
1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2,
1, 1
};
// Fixed traversal strategies for Pohlig-Hellman discrete logs
static const unsigned int ph2_path[PLEN_2] = { // w_2 = 5
0, 0, 1, 2, 3, 4, 4, 5, 5, 6, 7, 7, 8, 9, 10, 10, 11, 12, 13, 13, 14, 14, 15, 16, 17, 18,
18, 18, 19, 20, 20, 21, 22, 23, 24, 25, 25, 25, 25, 26, 27, 28, 29, 29, 30, 31, 32, 33, 34,
35, 35, 35, 35, 35, 36, 37, 38, 39, 40, 41, 41, 42};
0, 0, 1, 2, 3, 4, 4, 5, 5, 6, 7, 7, 8, 9, 10, 10, 11, 12, 13, 13, 14, 14, 15, 16, 17, 18,
18, 18, 19, 20, 20, 21, 22, 23, 24, 25, 25, 25, 25, 26, 27, 28, 29, 29, 30, 31, 32, 33, 34,
35, 35, 35, 35, 35, 36, 37, 38, 39, 40, 41, 41, 42
};
static const unsigned int ph3_path[PLEN_3] = { // w_3 = 6
0, 0, 1, 2, 3, 4, 5, 6, 6, 7, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 16, 16, 17, 18, 19,
20, 21, 21, 22, 23, 24, 25};
0, 0, 1, 2, 3, 4, 5, 6, 6, 7, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 16, 16, 17, 18, 19,
20, 21, 21, 22, 23, 24, 25
};
// Entangled bases related static tables and parameters
@ -198,145 +215,152 @@ static const unsigned int ph3_path[PLEN_3] = { // w_3 = 6
// A table of size 20 for values v = 1/(1+U*r^2) where U = 4+i
static const uint64_t u_entang[2 * NWORDS64_FIELD] = {
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xCE1991CC, 0x0, 0x0, 0x0, 0x3468000000000000, 0x9B33857A50E2F47F, 0x149430734647A838, 0xA56C442BA0D5A3C4, 0x26D204DD0C595E7B, 0x21129D2C8};
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xCE1991CC, 0x0, 0x0, 0x0, 0x3468000000000000, 0x9B33857A50E2F47F, 0x149430734647A838, 0xA56C442BA0D5A3C4, 0x26D204DD0C595E7B, 0x21129D2C8
};
static const uint64_t u0_entang[2 * NWORDS64_FIELD] = {
0x670CC8E6, 0x0, 0x0, 0x0, 0x9A34000000000000, 0x4D99C2BD28717A3F, 0xA4A1839A323D41C, 0xD2B62215D06AD1E2, 0x1369026E862CAF3D, 0x10894E964, 0x670CC8E6, 0x0, 0x0, 0x0, 0x9A34000000000000,
0x4D99C2BD28717A3F, 0xA4A1839A323D41C, 0xD2B62215D06AD1E2, 0x1369026E862CAF3D, 0x10894E964};
0x670CC8E6, 0x0, 0x0, 0x0, 0x9A34000000000000, 0x4D99C2BD28717A3F, 0xA4A1839A323D41C, 0xD2B62215D06AD1E2, 0x1369026E862CAF3D, 0x10894E964, 0x670CC8E6, 0x0, 0x0, 0x0, 0x9A34000000000000,
0x4D99C2BD28717A3F, 0xA4A1839A323D41C, 0xD2B62215D06AD1E2, 0x1369026E862CAF3D, 0x10894E964
};
// Tables for quadratic residues and quadratic non residues v with 17 elements each.
static const uint64_t table_r_qr[TABLE_R_LEN][NWORDS64_FIELD] =
{{0x670CC8E6, 0x0, 0x0, 0x0, 0x9A34000000000000, 0x4D99C2BD28717A3F, 0xA4A1839A323D41C, 0xD2B62215D06AD1E2, 0x1369026E862CAF3D, 0x10894E964},
{0x19C332399, 0x0, 0x0, 0x0, 0xFACE000000000000, 0x84EEBD0BF76B38CF, 0x8E40A1A187FF56C5, 0x9882D55D30E7225D, 0xCC13F8F7C6CAE46A, 0x1A65CFE27},
{0x338664733, 0x0, 0x0, 0x0, 0x879A000000000000, 0x58652C2F447BC171, 0x819983FE0B6EB3DF, 0x7EAFF7C0510A1F90, 0x1697E12D3BADF048, 0xD0C354E7},
{0x39F731019, 0x0, 0x0, 0x0, 0x21CE000000000000, 0xA5FEEEEC6CED3BB1, 0x8BE39C37AE9287FB, 0x516619D62174F172, 0x2A00E39BC1DA9F86, 0x1D9583E4B},
{0x4067FD900, 0x0, 0x0, 0x0, 0x4E00000000000000, 0x422063C0EB0405C2, 0xFB45F52C4D26626C, 0x71C688F1E11B9E29, 0xBBD9D547F61F7637, 0x65F68046},
{0x46D8CA1E6, 0x0, 0x0, 0x0, 0xE834000000000000, 0x8FBA267E13758001, 0x5900D65F04A3688, 0x447CAB07B186700C, 0xCF42D7B67C4C2575, 0x16E8B69AA},
{0x53BA633B3, 0x0, 0x0, 0x0, 0xAE9A000000000000, 0x79755E0FB9FDC452, 0x7F3C7E943201E515, 0x37933C394197EEA5, 0x7484CBD136BDAB64, 0x103BE950A},
{0x5A2B2FC99, 0x0, 0x0, 0x0, 0x48CE000000000000, 0xC70F20CCE26F3E92, 0x898696CDD525B931, 0xA495E4F1202C087, 0x87EDCE3FBCEA5AA2, 0x20C537E6E},
{0x609BFC580, 0x0, 0x0, 0x0, 0x7500000000000000, 0x633095A1608608A3, 0xF8E8EFC273B993A2, 0x2AA9CD6AD1A96D3E, 0x19C6BFEBF12F3153, 0x98F1C06A},
{0x7A5F2E919, 0x0, 0x0, 0x0, 0x6FCE000000000000, 0xE81F52AD57F14173, 0x87299163FBB8EA67, 0xC32CA2C802908F9C, 0xE5DAB8E3B7FA15BD, 0x23F4EBE91},
{0x9A932D599, 0x0, 0x0, 0x0, 0x96CE000000000000, 0x92F848DCD734454, 0x84CC8BFA224C1B9E, 0x7C0FE740F31E5EB1, 0x43C7A387B309D0D9, 0x27249FEB5},
{0xA103F9E80, 0x0, 0x0, 0x0, 0xC300000000000000, 0xA550F9624B8A0E65, 0xF42EE4EEC0DFF60E, 0x9C70565CB2C50B68, 0xD5A09533E74EA78A, 0xFEE840B0},
{0xA774C6766, 0x0, 0x0, 0x0, 0x5D34000000000000, 0xF2EABC1F73FB88A5, 0xFE78FD286403CA2A, 0x6F267872832FDD4A, 0xE90997A26D7B56C8, 0x2077D2A14},
{0xADE59304D, 0x0, 0x0, 0x0, 0x8966000000000000, 0x8F0C30F3F21252B6, 0x6DDB561D0297A49B, 0x8F86E78E42D68A02, 0x7AE2894EA1C02D79, 0x941B6C10},
{0xB4565F933, 0x0, 0x0, 0x0, 0x239A000000000000, 0xDCA5F3B11A83CCF6, 0x78256E56A5BB78B7, 0x623D09A413415BE4, 0x8E4B8BBD27ECDCB7, 0x19CB05574},
{0xBAC72C21A, 0x0, 0x0, 0x0, 0x4FCC000000000000, 0x78C76885989A9707, 0xE787C74B444F5328, 0x829D78BFD2E8089B, 0x20247D695C31B368, 0x294E9770},
{0xC137F8B00, 0x0, 0x0, 0x0, 0xEA00000000000000, 0xC6612B42C10C1146, 0xF1D1DF84E7732744, 0x55539AD5A352DA7D, 0x338D7FD7E25E62A6, 0x131E380D4}};
static const uint64_t table_r_qr[TABLE_R_LEN][NWORDS64_FIELD] = {
{0x670CC8E6, 0x0, 0x0, 0x0, 0x9A34000000000000, 0x4D99C2BD28717A3F, 0xA4A1839A323D41C, 0xD2B62215D06AD1E2, 0x1369026E862CAF3D, 0x10894E964},
{0x19C332399, 0x0, 0x0, 0x0, 0xFACE000000000000, 0x84EEBD0BF76B38CF, 0x8E40A1A187FF56C5, 0x9882D55D30E7225D, 0xCC13F8F7C6CAE46A, 0x1A65CFE27},
{0x338664733, 0x0, 0x0, 0x0, 0x879A000000000000, 0x58652C2F447BC171, 0x819983FE0B6EB3DF, 0x7EAFF7C0510A1F90, 0x1697E12D3BADF048, 0xD0C354E7},
{0x39F731019, 0x0, 0x0, 0x0, 0x21CE000000000000, 0xA5FEEEEC6CED3BB1, 0x8BE39C37AE9287FB, 0x516619D62174F172, 0x2A00E39BC1DA9F86, 0x1D9583E4B},
{0x4067FD900, 0x0, 0x0, 0x0, 0x4E00000000000000, 0x422063C0EB0405C2, 0xFB45F52C4D26626C, 0x71C688F1E11B9E29, 0xBBD9D547F61F7637, 0x65F68046},
{0x46D8CA1E6, 0x0, 0x0, 0x0, 0xE834000000000000, 0x8FBA267E13758001, 0x5900D65F04A3688, 0x447CAB07B186700C, 0xCF42D7B67C4C2575, 0x16E8B69AA},
{0x53BA633B3, 0x0, 0x0, 0x0, 0xAE9A000000000000, 0x79755E0FB9FDC452, 0x7F3C7E943201E515, 0x37933C394197EEA5, 0x7484CBD136BDAB64, 0x103BE950A},
{0x5A2B2FC99, 0x0, 0x0, 0x0, 0x48CE000000000000, 0xC70F20CCE26F3E92, 0x898696CDD525B931, 0xA495E4F1202C087, 0x87EDCE3FBCEA5AA2, 0x20C537E6E},
{0x609BFC580, 0x0, 0x0, 0x0, 0x7500000000000000, 0x633095A1608608A3, 0xF8E8EFC273B993A2, 0x2AA9CD6AD1A96D3E, 0x19C6BFEBF12F3153, 0x98F1C06A},
{0x7A5F2E919, 0x0, 0x0, 0x0, 0x6FCE000000000000, 0xE81F52AD57F14173, 0x87299163FBB8EA67, 0xC32CA2C802908F9C, 0xE5DAB8E3B7FA15BD, 0x23F4EBE91},
{0x9A932D599, 0x0, 0x0, 0x0, 0x96CE000000000000, 0x92F848DCD734454, 0x84CC8BFA224C1B9E, 0x7C0FE740F31E5EB1, 0x43C7A387B309D0D9, 0x27249FEB5},
{0xA103F9E80, 0x0, 0x0, 0x0, 0xC300000000000000, 0xA550F9624B8A0E65, 0xF42EE4EEC0DFF60E, 0x9C70565CB2C50B68, 0xD5A09533E74EA78A, 0xFEE840B0},
{0xA774C6766, 0x0, 0x0, 0x0, 0x5D34000000000000, 0xF2EABC1F73FB88A5, 0xFE78FD286403CA2A, 0x6F267872832FDD4A, 0xE90997A26D7B56C8, 0x2077D2A14},
{0xADE59304D, 0x0, 0x0, 0x0, 0x8966000000000000, 0x8F0C30F3F21252B6, 0x6DDB561D0297A49B, 0x8F86E78E42D68A02, 0x7AE2894EA1C02D79, 0x941B6C10},
{0xB4565F933, 0x0, 0x0, 0x0, 0x239A000000000000, 0xDCA5F3B11A83CCF6, 0x78256E56A5BB78B7, 0x623D09A413415BE4, 0x8E4B8BBD27ECDCB7, 0x19CB05574},
{0xBAC72C21A, 0x0, 0x0, 0x0, 0x4FCC000000000000, 0x78C76885989A9707, 0xE787C74B444F5328, 0x829D78BFD2E8089B, 0x20247D695C31B368, 0x294E9770},
{0xC137F8B00, 0x0, 0x0, 0x0, 0xEA00000000000000, 0xC6612B42C10C1146, 0xF1D1DF84E7732744, 0x55539AD5A352DA7D, 0x338D7FD7E25E62A6, 0x131E380D4}
};
static const uint64_t table_r_qnr[TABLE_R_LEN][NWORDS64_FIELD] =
{{0xCE1991CC, 0x0, 0x0, 0x0, 0x3468000000000000, 0x9B33857A50E2F47F, 0x149430734647A838, 0xA56C442BA0D5A3C4, 0x26D204DD0C595E7B, 0x21129D2C8},
{0x135265AB3, 0x0, 0x0, 0x0, 0x609A000000000000, 0x3754FA4ECEF9BE90, 0x83F68967E4DB82A9, 0xC5CCB347607C507B, 0xB8AAF689409E352C, 0x9DC814C3},
{0x2033FEC80, 0x0, 0x0, 0x0, 0x2700000000000000, 0x211031E0758202E1, 0xFDA2FA9626933136, 0xB8E34478F08DCF14, 0x5DECEAA3FB0FBB1B, 0x32FB4023},
{0x26A4CB566, 0x0, 0x0, 0x0, 0xC134000000000000, 0x6EA9F49D9DF37D20, 0x7ED12CFC9B70552, 0x8B99668EC0F8A0F7, 0x7155ED12813C6A59, 0x13B902987},
{0x2D1597E4C, 0x0, 0x0, 0x0, 0x5B68000000000000, 0xBC43B75AC664F760, 0x12372B096CDAD96E, 0x5E4F88A4916372D9, 0x84BEEF8107691997, 0x2442512EB},
{0x4D4996ACC, 0x0, 0x0, 0x0, 0x8268000000000000, 0xDD53E93B3BE6FA41, 0xFDA259F936E0AA4, 0x1732CD1D81F141EE, 0xE2ABDA250278D4B3, 0x27720530E},
{0x670CC8E66, 0x0, 0x0, 0x0, 0xF34000000000000, 0xB0CA585E88F782E3, 0x33307FC16DD67BE, 0xFD5FEF80A2143F21, 0x2D2FC25A775BE090, 0x1A186A9CE},
{0x6D7D9574D, 0x0, 0x0, 0x0, 0x3B66000000000000, 0x4CEBCD33070E4CF4, 0x729560F0B571422F, 0x1DC05E9C61BAEBD8, 0xBF08B406ABA0B742, 0x2E24EBC9},
{0x73EE62033, 0x0, 0x0, 0x0, 0xD59A000000000000, 0x9A858FF02F7FC733, 0x7CDF792A5895164B, 0xF07680B23225BDBA, 0xD271B67531CD667F, 0x136B9D52D},
{0x80CFFB200, 0x0, 0x0, 0x0, 0x9C00000000000000, 0x8440C781D6080B84, 0xF68BEA589A4CC4D8, 0xE38D11E3C2373C53, 0x77B3AA8FEC3EEC6E, 0xCBED008D},
{0x8740C7AE6, 0x0, 0x0, 0x0, 0x3634000000000000, 0xD1DA8A3EFE7985C4, 0xD602923D7098F4, 0xB64333F992A20E36, 0x8B1CACFE726B9BAC, 0x1D481E9F1},
{0x8DB1943CD, 0x0, 0x0, 0x0, 0x6266000000000000, 0x6DFBFF137C904FD5, 0x70385B86DC047365, 0xD6A3A3155248BAED, 0x1CF59EAAA6B0725D, 0x61202BED},
{0x942260CB3, 0x0, 0x0, 0x0, 0xFC9A000000000000, 0xBB95C1D0A501CA14, 0x7A8273C07F284781, 0xA959C52B22B38CCF, 0x305EA1192CDD219B, 0x169B51551},
{0xCE1991CCD, 0x0, 0x0, 0x0, 0xB066000000000000, 0xB01C62D467945597, 0x6B7E50B3292AD5D1, 0x486A2C0733645917, 0xD8CF73F29CCFE895, 0xC716AC33},
{0xD48A5E5B3, 0x0, 0x0, 0x0, 0x4A9A000000000000, 0xFDB625919005CFD7, 0x75C868ECCC4EA9ED, 0x1B204E1D03CF2AF9, 0xEC38766122FC97D3, 0x1CFAB9597},
{0xDAFB2AE9A, 0x0, 0x0, 0x0, 0x76CC000000000000, 0x99D79A660E1C99E8, 0xE52AC1E16AE2845E, 0x3B80BD38C375D7B0, 0x7E11680D57416E84, 0x5C49D793},
{0xE7DCC4066, 0x0, 0x0, 0x0, 0xAB34000000000000, 0x350B1FE05EFF8E67, 0xF9BEF254B12A2C97, 0xE0ED0164644B7B74, 0xA4E36CEA639ACCFF, 0x26D73AA5B}};
static const uint64_t table_r_qnr[TABLE_R_LEN][NWORDS64_FIELD] = {
{0xCE1991CC, 0x0, 0x0, 0x0, 0x3468000000000000, 0x9B33857A50E2F47F, 0x149430734647A838, 0xA56C442BA0D5A3C4, 0x26D204DD0C595E7B, 0x21129D2C8},
{0x135265AB3, 0x0, 0x0, 0x0, 0x609A000000000000, 0x3754FA4ECEF9BE90, 0x83F68967E4DB82A9, 0xC5CCB347607C507B, 0xB8AAF689409E352C, 0x9DC814C3},
{0x2033FEC80, 0x0, 0x0, 0x0, 0x2700000000000000, 0x211031E0758202E1, 0xFDA2FA9626933136, 0xB8E34478F08DCF14, 0x5DECEAA3FB0FBB1B, 0x32FB4023},
{0x26A4CB566, 0x0, 0x0, 0x0, 0xC134000000000000, 0x6EA9F49D9DF37D20, 0x7ED12CFC9B70552, 0x8B99668EC0F8A0F7, 0x7155ED12813C6A59, 0x13B902987},
{0x2D1597E4C, 0x0, 0x0, 0x0, 0x5B68000000000000, 0xBC43B75AC664F760, 0x12372B096CDAD96E, 0x5E4F88A4916372D9, 0x84BEEF8107691997, 0x2442512EB},
{0x4D4996ACC, 0x0, 0x0, 0x0, 0x8268000000000000, 0xDD53E93B3BE6FA41, 0xFDA259F936E0AA4, 0x1732CD1D81F141EE, 0xE2ABDA250278D4B3, 0x27720530E},
{0x670CC8E66, 0x0, 0x0, 0x0, 0xF34000000000000, 0xB0CA585E88F782E3, 0x33307FC16DD67BE, 0xFD5FEF80A2143F21, 0x2D2FC25A775BE090, 0x1A186A9CE},
{0x6D7D9574D, 0x0, 0x0, 0x0, 0x3B66000000000000, 0x4CEBCD33070E4CF4, 0x729560F0B571422F, 0x1DC05E9C61BAEBD8, 0xBF08B406ABA0B742, 0x2E24EBC9},
{0x73EE62033, 0x0, 0x0, 0x0, 0xD59A000000000000, 0x9A858FF02F7FC733, 0x7CDF792A5895164B, 0xF07680B23225BDBA, 0xD271B67531CD667F, 0x136B9D52D},
{0x80CFFB200, 0x0, 0x0, 0x0, 0x9C00000000000000, 0x8440C781D6080B84, 0xF68BEA589A4CC4D8, 0xE38D11E3C2373C53, 0x77B3AA8FEC3EEC6E, 0xCBED008D},
{0x8740C7AE6, 0x0, 0x0, 0x0, 0x3634000000000000, 0xD1DA8A3EFE7985C4, 0xD602923D7098F4, 0xB64333F992A20E36, 0x8B1CACFE726B9BAC, 0x1D481E9F1},
{0x8DB1943CD, 0x0, 0x0, 0x0, 0x6266000000000000, 0x6DFBFF137C904FD5, 0x70385B86DC047365, 0xD6A3A3155248BAED, 0x1CF59EAAA6B0725D, 0x61202BED},
{0x942260CB3, 0x0, 0x0, 0x0, 0xFC9A000000000000, 0xBB95C1D0A501CA14, 0x7A8273C07F284781, 0xA959C52B22B38CCF, 0x305EA1192CDD219B, 0x169B51551},
{0xCE1991CCD, 0x0, 0x0, 0x0, 0xB066000000000000, 0xB01C62D467945597, 0x6B7E50B3292AD5D1, 0x486A2C0733645917, 0xD8CF73F29CCFE895, 0xC716AC33},
{0xD48A5E5B3, 0x0, 0x0, 0x0, 0x4A9A000000000000, 0xFDB625919005CFD7, 0x75C868ECCC4EA9ED, 0x1B204E1D03CF2AF9, 0xEC38766122FC97D3, 0x1CFAB9597},
{0xDAFB2AE9A, 0x0, 0x0, 0x0, 0x76CC000000000000, 0x99D79A660E1C99E8, 0xE52AC1E16AE2845E, 0x3B80BD38C375D7B0, 0x7E11680D57416E84, 0x5C49D793},
{0xE7DCC4066, 0x0, 0x0, 0x0, 0xAB34000000000000, 0x350B1FE05EFF8E67, 0xF9BEF254B12A2C97, 0xE0ED0164644B7B74, 0xA4E36CEA639ACCFF, 0x26D73AA5B}
};
static const uint64_t table_v_qr[TABLE_V_LEN][NWORDS64_FIELD] =
{{0xCCCCCCCCE168F4FA, 0xCCCCCCCCCCCCCCCC, 0xCCCCCCCCCCCCCCCC, 0xCCCCCCCCCCCCCCCC, 0x76D8CCCCCCCCCCCC, 0x3E565465D2C0BCB, 0xB12E9DDC577A588F, 0x1F35C932D0B247B5, 0x521DAB18F8F36B0, 0x231AFE7CE},
{0x666666663D2E160A, 0x6666666666666666, 0x6666666666666666, 0x6666666666666666, 0xEE52666666666666, 0x5B25D1449A5D48C5, 0xD37242D15A2B4239, 0x263FD38E8023BAE9, 0xF8DC6C2184B143B9, 0x948D7F34},
{0x2B7522B7524531E5, 0x22B7522B7522B752, 0x522B7522B7522B75, 0x7522B7522B7522B7, 0xED882B7522B7522B, 0xF1639645024AE01, 0x4F035B12DE5E50A0, 0x73C4980ACDD7F1A1, 0xA42840C6580DE412, 0x1DD62C7C0},
{0x915BA915B759C347, 0xA915BA915BA915BA, 0xBA915BA915BA915B, 0x5BA915BA915BA915, 0xD2C915BA915BA91, 0x71F86F2E9E45744B, 0x40364B61A6454DC2, 0xF1CB7911E8296CFF, 0x22098A2EFDE7A36E, 0x26EBD6120},
{0xAD9149BAD91637DA, 0x9BAD9149BAD9149B, 0x149BAD9149BAD914, 0xD9149BAD9149BAD9, 0x9F25149BAD9149BA, 0xD62B18FB0FE869F1, 0xC55BADFBDB1E3966, 0xD3983013C35F72D3, 0xCDCBA5EC343A38C7, 0xA9663F71},
{0x375B229374E412DD, 0x29375B229375B229, 0xB229375B229375B2, 0x75B229375B229375, 0x77BBB229375B2293, 0x2DE6294756311D89, 0x7FD8288210926F0E, 0x959F6E4E9B17AAF0, 0xD0DF547715963752, 0x23F992A62},
{0x95AB46517CB6558, 0xF00AC4C8322D018D, 0xC4BBB5E824213413, 0xFE54FF999E981B8B, 0x457485163ADB696E, 0xB3837BF2C2444F67, 0xAE6D4CC9D80D6369, 0x16560F053370AC84, 0x23263644FE26E906, 0x70C8ECA4},
{0x1499D806F149DE33, 0x192F79503F8504C0, 0x8136E31922FD0B62, 0xE3640C9A3BE918D, 0x827DC7EEC12747C3, 0x816C63BC5D0BB5E8, 0x2B161316CBD65F8F, 0x113FC50958EB09DD, 0x6F238E5A72A41216, 0xABCB36F8},
{0x84665F30F3CF95E5, 0xC3B84BD34725A330, 0x3A6AF0FAC575EE0A, 0x9C71AFCF5C78A658, 0xB84BA4EE269DDBC3, 0x8E25FEED6714479A, 0x6FA95E8F73EA96FC, 0x4E8F67FDBB4C1B14, 0x9F723476F170C736, 0xBA3A5C22},
{0x9005A1C185D2E4DD, 0x1804C2F06A988218, 0x5C73BC15BBDE0797, 0xC72EA5FFC1BE0B12, 0x5F5D25F1D4AC4F2D, 0xD90ACB26BB0EA9D3, 0x771734D57DE89542, 0xB9B7016789BF68DA, 0x4AFADFDC405345FF, 0x114409A09},
{0x69E362D42702ACE6, 0x9FC36EB7EA12F1E0, 0x9CCA7DF3BC005DFF, 0xD8FB897860F89087, 0x684E603A54569145, 0x59A0620287865C95, 0xA1EE61177C586BBF, 0xDDBC6767DA8F6EE1, 0x9C092A6A8396897F, 0x27991721C},
{0xE70C93731F788DA2, 0xF9415624BA1759DB, 0xC894EF9847A7245A, 0xE2380C3455075FCD, 0x63CD08DC462AABF8, 0xA1CFF8CECB706A7, 0x5BBB070AC484296B, 0xF8E970373DD450FB, 0xF985BF0108DCBA20, 0x243AC61BE},
{0x886DC36536F16AC0, 0xCE46420B9809323C, 0x8F0CE1E1A569DA62, 0x574F7A978263CAAD, 0x93BE116009D2DB5C, 0xE47CE9FDE2BCB17A, 0xAEFCD1BFDE2FB352, 0x6596D37050A6FE96, 0xA936C53A6B044AC2, 0xBAE5C165},
{0xDF14045D75410E1C, 0xA73CCCB143DBAC13, 0x20FDC4139A3DA98B, 0xB91023F5D83E66D9, 0xE7D50F33079A6014, 0xA6117DAD2E4A7E4B, 0x78B9C7A26D42C39F, 0x8856BF64102261B1, 0x31F624C6B2E5E24B, 0x1A9000C99},
{0x4D1B7C9879B8F55E, 0x2A149D570FBDDE34, 0xB2B6E11841366015, 0xBCF5C4F2C545EF76, 0x939396F37CA988F0, 0x2F66041FC5F19298, 0x60D9027E6FDDE5C8, 0x594434D0D278B451, 0xDABB15ADAEA1D3E7, 0x24D1C996F},
{0xEDE936859CC846A4, 0x906F12AFE543BFE9, 0x57F752DC24BCDF97, 0xA7AA6C41ECE9523E, 0x70D8DB291C664F5E, 0xC2D8762B1F0A0862, 0xF538248730EF2597, 0xE1699BCD8E10BBF7, 0x4A5EA2590DDB6DCC, 0x22EEB1551},
{0xF2A95939B0FDB788, 0x220AC9E23E53C0A, 0x37C7FB2D043F1549, 0x17A39CE70F0B8E54, 0xF8D84DD2D87A4331, 0xCC560AC3C2D4ECB1, 0x29AFE290E4B8470D, 0x5FD3854406911AD1, 0x16284324DEA12E26, 0x265A1E3E1},
{0x72512896E203613D, 0x42909204E70C74C1, 0xF2787ADE891C95AA, 0x726631D78DAFCFF5, 0x812D335F7915E3B4, 0x602D763CFDD14E0D, 0xF09DBF94B4B8587D, 0x95CEDD56F23A03B9, 0x35067361D5A1D79E, 0x1FD8BE4EB},
{0x401CA1FC04E9C123, 0x90C26307F5CC0A0F, 0x485D5BE49E59B0C3, 0x4FE729949842C2E, 0xDFE318C2AE76911B, 0xD12311AD4DD78EA1, 0xE40CA0745241900F, 0x3D124917B409965B, 0xBFD7D5AFE6476F0, 0x6D74FB8C},
{0x2F3F273A24BD4ACD, 0xBBC4B38CC68BA0FD, 0xE8B2D539670B7871, 0xEA60CBAEA93B6577, 0x487E2AEFF59AC1CB, 0xD2D62FD5A457C222, 0x778BDCA33D649C39, 0xD6463F406CBC16A4, 0x726CA44086DD4B26, 0x1D3824D0D},
{0xBDB1260A3702AD09, 0x2D6B1A339991FEBC, 0xAA9F6C83305EA847, 0xA046C8AD7DFDC0E3, 0xD44F15831B61D266, 0xE5069559BBEFA954, 0xD78E56E41C84CC4E, 0x760438E0D334C5E, 0xAD70552405CB2442, 0x26FADBB00},
{0x62D4D20873F55316, 0x9E0A17CCEF05AEAA, 0x3297B1A6560ABFB3, 0xC178F3490A1BFF80, 0x30F33204C7CD322E, 0xBF67D1323DD3AF36, 0xC26B4425CDECACD6, 0xFD1804929AF46345, 0x6C6AD7A3773EB3E9, 0xA0F5703F},
{0x7B5586A15EEE987A, 0x712704F03450E84C, 0x6FDC36F98F02AC0C, 0xA1B5EBF84C82B74F, 0x70B06DBC6C6FBB4, 0xF49DA4BBBBB4A081, 0xD539B581C8C78E70, 0xC505DC913CDC308A, 0x79302B7361615850, 0x1FDAD6EA8},
{0xC864A00E76FB7862, 0x7F79E3208CF1BA8D, 0xCEBB9173B4F3EB3F, 0x65B5CD9A69BCEE1F, 0x2FFC82DF6866F802, 0x372294003EFDDFB6, 0x2B4A606D7D21B67A, 0xFCCF899A749472DD, 0x60AD6F3318245C4F, 0x8A94EC6B},
{0x3B540A505CFDE08A, 0x1F4FA2605E47B5FD, 0x545260EAD2FAFEEF, 0xEACCE2AB9D6A73E1, 0x4DE929F08605608A, 0x7FD4E8C4330111E9, 0xACA7C41ABA9F32CB, 0x81CE18FFB987259B, 0xCF27FAA2E00078FC, 0x13C2D3CF2},
{0xAC298794E336248F, 0xA36E730E1546DE9E, 0xACF027D5C26DA122, 0xF5F2E5A8A5CC01FA, 0xBBDC81BC339A2257, 0x70D7847A7AC291EB, 0x653A274765BB19A2, 0x4AD77CDA41E716D9, 0x909862AA50015453, 0x214843766},
{0x28DCFDDEE7E75520, 0x926112237D3B1FF5, 0x1C7EF82595F8671, 0x1506781F7F3CBDFF, 0x6085630169990327, 0xE99E1AB62629523A, 0xF5124A3DA6D4B381, 0x6238E3E6BA5CD147, 0xFF73FD00F4AE2505, 0x267B4E1A7},
{0x4562207B3C7D2A3C, 0x5326B1E0C543FDBD, 0xDB4DEB9EFDF44D2C, 0x4127DC9D580DE9A7, 0xB5A21F4968C0B6A, 0x551995E644DD6F9D, 0xA410258D02B6BD1A, 0x38AD3333153D132C, 0xBC05805A3AF78F5E, 0x118462D9D},
{0x6BCC76AD0919255E, 0x1CE349F8E0113FDD, 0x9FDDB44D41754041, 0x17B14F71175D7A86, 0xFF025B1D9403E728, 0xB066EF99669BAC1, 0x823A70C11307F544, 0xE302A74F2C217B92, 0x44959A86BE1185DF, 0x1AAAE7CC1},
{0xBBA91C2845FB1C23, 0xFDAEBA39658D3CB, 0xD20FA6CF11D6712F, 0xE1F96B50E371876C, 0x8FCBEAD568182A6E, 0x7470BD4B6F6ECAC0, 0x854B204F3377B675, 0x1A4069A8A9B7FEE1, 0xD94275FEBB51BF6B, 0x278D27918},
{0x6426BB8949C81154, 0xF8E70C86ACAADADD, 0x254018F73FF1D13, 0x299DE9B99FB375F3, 0xFAD85F5B9455BC3D, 0x75B38230DECC8C86, 0x84D8352EC4455A3E, 0xC63E8F4D14896C61, 0xABDCAF24FBE2620C, 0x18DD5BB6F},
{0xF983D3F93B7E21FB, 0xA1EFB325856DFD63, 0xB40DBF77DDD2F2C6, 0x90765A64B6E3095A, 0x5C97784B64B13624, 0xA66B10ECDB13601E, 0x56B0519E348B08D7, 0x377A62607E2C784, 0xBD9E2E4BF13D82CB, 0x1FF451525},
{0x10BEA3C10F74187C, 0xD1A28B48103C996B, 0x71DE9B27B2DEE637, 0xCCD9CF6314DF24F6, 0xA3509CFF5B01D17C, 0xBD870219DBDE553D, 0xC24847905D600F2, 0x3F6029BE326908F1, 0x956902BB0608AF31, 0x19FBAFFCD},
{0x43909A8B57B3D387, 0x11CAD4DD5E94732, 0x5ACD10DE50BD4786, 0xA485CF553F041B2F, 0x78621C881B370A7F, 0x54D76CE547ACAC13, 0xD2BAF160F13C3B9E, 0x4FDE5E64A3480204, 0x2501DA6825E2CC9A, 0xD63111F9}};
static const uint64_t table_v_qr[TABLE_V_LEN][NWORDS64_FIELD] = {
{0xCCCCCCCCE168F4FA, 0xCCCCCCCCCCCCCCCC, 0xCCCCCCCCCCCCCCCC, 0xCCCCCCCCCCCCCCCC, 0x76D8CCCCCCCCCCCC, 0x3E565465D2C0BCB, 0xB12E9DDC577A588F, 0x1F35C932D0B247B5, 0x521DAB18F8F36B0, 0x231AFE7CE},
{0x666666663D2E160A, 0x6666666666666666, 0x6666666666666666, 0x6666666666666666, 0xEE52666666666666, 0x5B25D1449A5D48C5, 0xD37242D15A2B4239, 0x263FD38E8023BAE9, 0xF8DC6C2184B143B9, 0x948D7F34},
{0x2B7522B7524531E5, 0x22B7522B7522B752, 0x522B7522B7522B75, 0x7522B7522B7522B7, 0xED882B7522B7522B, 0xF1639645024AE01, 0x4F035B12DE5E50A0, 0x73C4980ACDD7F1A1, 0xA42840C6580DE412, 0x1DD62C7C0},
{0x915BA915B759C347, 0xA915BA915BA915BA, 0xBA915BA915BA915B, 0x5BA915BA915BA915, 0xD2C915BA915BA91, 0x71F86F2E9E45744B, 0x40364B61A6454DC2, 0xF1CB7911E8296CFF, 0x22098A2EFDE7A36E, 0x26EBD6120},
{0xAD9149BAD91637DA, 0x9BAD9149BAD9149B, 0x149BAD9149BAD914, 0xD9149BAD9149BAD9, 0x9F25149BAD9149BA, 0xD62B18FB0FE869F1, 0xC55BADFBDB1E3966, 0xD3983013C35F72D3, 0xCDCBA5EC343A38C7, 0xA9663F71},
{0x375B229374E412DD, 0x29375B229375B229, 0xB229375B229375B2, 0x75B229375B229375, 0x77BBB229375B2293, 0x2DE6294756311D89, 0x7FD8288210926F0E, 0x959F6E4E9B17AAF0, 0xD0DF547715963752, 0x23F992A62},
{0x95AB46517CB6558, 0xF00AC4C8322D018D, 0xC4BBB5E824213413, 0xFE54FF999E981B8B, 0x457485163ADB696E, 0xB3837BF2C2444F67, 0xAE6D4CC9D80D6369, 0x16560F053370AC84, 0x23263644FE26E906, 0x70C8ECA4},
{0x1499D806F149DE33, 0x192F79503F8504C0, 0x8136E31922FD0B62, 0xE3640C9A3BE918D, 0x827DC7EEC12747C3, 0x816C63BC5D0BB5E8, 0x2B161316CBD65F8F, 0x113FC50958EB09DD, 0x6F238E5A72A41216, 0xABCB36F8},
{0x84665F30F3CF95E5, 0xC3B84BD34725A330, 0x3A6AF0FAC575EE0A, 0x9C71AFCF5C78A658, 0xB84BA4EE269DDBC3, 0x8E25FEED6714479A, 0x6FA95E8F73EA96FC, 0x4E8F67FDBB4C1B14, 0x9F723476F170C736, 0xBA3A5C22},
{0x9005A1C185D2E4DD, 0x1804C2F06A988218, 0x5C73BC15BBDE0797, 0xC72EA5FFC1BE0B12, 0x5F5D25F1D4AC4F2D, 0xD90ACB26BB0EA9D3, 0x771734D57DE89542, 0xB9B7016789BF68DA, 0x4AFADFDC405345FF, 0x114409A09},
{0x69E362D42702ACE6, 0x9FC36EB7EA12F1E0, 0x9CCA7DF3BC005DFF, 0xD8FB897860F89087, 0x684E603A54569145, 0x59A0620287865C95, 0xA1EE61177C586BBF, 0xDDBC6767DA8F6EE1, 0x9C092A6A8396897F, 0x27991721C},
{0xE70C93731F788DA2, 0xF9415624BA1759DB, 0xC894EF9847A7245A, 0xE2380C3455075FCD, 0x63CD08DC462AABF8, 0xA1CFF8CECB706A7, 0x5BBB070AC484296B, 0xF8E970373DD450FB, 0xF985BF0108DCBA20, 0x243AC61BE},
{0x886DC36536F16AC0, 0xCE46420B9809323C, 0x8F0CE1E1A569DA62, 0x574F7A978263CAAD, 0x93BE116009D2DB5C, 0xE47CE9FDE2BCB17A, 0xAEFCD1BFDE2FB352, 0x6596D37050A6FE96, 0xA936C53A6B044AC2, 0xBAE5C165},
{0xDF14045D75410E1C, 0xA73CCCB143DBAC13, 0x20FDC4139A3DA98B, 0xB91023F5D83E66D9, 0xE7D50F33079A6014, 0xA6117DAD2E4A7E4B, 0x78B9C7A26D42C39F, 0x8856BF64102261B1, 0x31F624C6B2E5E24B, 0x1A9000C99},
{0x4D1B7C9879B8F55E, 0x2A149D570FBDDE34, 0xB2B6E11841366015, 0xBCF5C4F2C545EF76, 0x939396F37CA988F0, 0x2F66041FC5F19298, 0x60D9027E6FDDE5C8, 0x594434D0D278B451, 0xDABB15ADAEA1D3E7, 0x24D1C996F},
{0xEDE936859CC846A4, 0x906F12AFE543BFE9, 0x57F752DC24BCDF97, 0xA7AA6C41ECE9523E, 0x70D8DB291C664F5E, 0xC2D8762B1F0A0862, 0xF538248730EF2597, 0xE1699BCD8E10BBF7, 0x4A5EA2590DDB6DCC, 0x22EEB1551},
{0xF2A95939B0FDB788, 0x220AC9E23E53C0A, 0x37C7FB2D043F1549, 0x17A39CE70F0B8E54, 0xF8D84DD2D87A4331, 0xCC560AC3C2D4ECB1, 0x29AFE290E4B8470D, 0x5FD3854406911AD1, 0x16284324DEA12E26, 0x265A1E3E1},
{0x72512896E203613D, 0x42909204E70C74C1, 0xF2787ADE891C95AA, 0x726631D78DAFCFF5, 0x812D335F7915E3B4, 0x602D763CFDD14E0D, 0xF09DBF94B4B8587D, 0x95CEDD56F23A03B9, 0x35067361D5A1D79E, 0x1FD8BE4EB},
{0x401CA1FC04E9C123, 0x90C26307F5CC0A0F, 0x485D5BE49E59B0C3, 0x4FE729949842C2E, 0xDFE318C2AE76911B, 0xD12311AD4DD78EA1, 0xE40CA0745241900F, 0x3D124917B409965B, 0xBFD7D5AFE6476F0, 0x6D74FB8C},
{0x2F3F273A24BD4ACD, 0xBBC4B38CC68BA0FD, 0xE8B2D539670B7871, 0xEA60CBAEA93B6577, 0x487E2AEFF59AC1CB, 0xD2D62FD5A457C222, 0x778BDCA33D649C39, 0xD6463F406CBC16A4, 0x726CA44086DD4B26, 0x1D3824D0D},
{0xBDB1260A3702AD09, 0x2D6B1A339991FEBC, 0xAA9F6C83305EA847, 0xA046C8AD7DFDC0E3, 0xD44F15831B61D266, 0xE5069559BBEFA954, 0xD78E56E41C84CC4E, 0x760438E0D334C5E, 0xAD70552405CB2442, 0x26FADBB00},
{0x62D4D20873F55316, 0x9E0A17CCEF05AEAA, 0x3297B1A6560ABFB3, 0xC178F3490A1BFF80, 0x30F33204C7CD322E, 0xBF67D1323DD3AF36, 0xC26B4425CDECACD6, 0xFD1804929AF46345, 0x6C6AD7A3773EB3E9, 0xA0F5703F},
{0x7B5586A15EEE987A, 0x712704F03450E84C, 0x6FDC36F98F02AC0C, 0xA1B5EBF84C82B74F, 0x70B06DBC6C6FBB4, 0xF49DA4BBBBB4A081, 0xD539B581C8C78E70, 0xC505DC913CDC308A, 0x79302B7361615850, 0x1FDAD6EA8},
{0xC864A00E76FB7862, 0x7F79E3208CF1BA8D, 0xCEBB9173B4F3EB3F, 0x65B5CD9A69BCEE1F, 0x2FFC82DF6866F802, 0x372294003EFDDFB6, 0x2B4A606D7D21B67A, 0xFCCF899A749472DD, 0x60AD6F3318245C4F, 0x8A94EC6B},
{0x3B540A505CFDE08A, 0x1F4FA2605E47B5FD, 0x545260EAD2FAFEEF, 0xEACCE2AB9D6A73E1, 0x4DE929F08605608A, 0x7FD4E8C4330111E9, 0xACA7C41ABA9F32CB, 0x81CE18FFB987259B, 0xCF27FAA2E00078FC, 0x13C2D3CF2},
{0xAC298794E336248F, 0xA36E730E1546DE9E, 0xACF027D5C26DA122, 0xF5F2E5A8A5CC01FA, 0xBBDC81BC339A2257, 0x70D7847A7AC291EB, 0x653A274765BB19A2, 0x4AD77CDA41E716D9, 0x909862AA50015453, 0x214843766},
{0x28DCFDDEE7E75520, 0x926112237D3B1FF5, 0x1C7EF82595F8671, 0x1506781F7F3CBDFF, 0x6085630169990327, 0xE99E1AB62629523A, 0xF5124A3DA6D4B381, 0x6238E3E6BA5CD147, 0xFF73FD00F4AE2505, 0x267B4E1A7},
{0x4562207B3C7D2A3C, 0x5326B1E0C543FDBD, 0xDB4DEB9EFDF44D2C, 0x4127DC9D580DE9A7, 0xB5A21F4968C0B6A, 0x551995E644DD6F9D, 0xA410258D02B6BD1A, 0x38AD3333153D132C, 0xBC05805A3AF78F5E, 0x118462D9D},
{0x6BCC76AD0919255E, 0x1CE349F8E0113FDD, 0x9FDDB44D41754041, 0x17B14F71175D7A86, 0xFF025B1D9403E728, 0xB066EF99669BAC1, 0x823A70C11307F544, 0xE302A74F2C217B92, 0x44959A86BE1185DF, 0x1AAAE7CC1},
{0xBBA91C2845FB1C23, 0xFDAEBA39658D3CB, 0xD20FA6CF11D6712F, 0xE1F96B50E371876C, 0x8FCBEAD568182A6E, 0x7470BD4B6F6ECAC0, 0x854B204F3377B675, 0x1A4069A8A9B7FEE1, 0xD94275FEBB51BF6B, 0x278D27918},
{0x6426BB8949C81154, 0xF8E70C86ACAADADD, 0x254018F73FF1D13, 0x299DE9B99FB375F3, 0xFAD85F5B9455BC3D, 0x75B38230DECC8C86, 0x84D8352EC4455A3E, 0xC63E8F4D14896C61, 0xABDCAF24FBE2620C, 0x18DD5BB6F},
{0xF983D3F93B7E21FB, 0xA1EFB325856DFD63, 0xB40DBF77DDD2F2C6, 0x90765A64B6E3095A, 0x5C97784B64B13624, 0xA66B10ECDB13601E, 0x56B0519E348B08D7, 0x377A62607E2C784, 0xBD9E2E4BF13D82CB, 0x1FF451525},
{0x10BEA3C10F74187C, 0xD1A28B48103C996B, 0x71DE9B27B2DEE637, 0xCCD9CF6314DF24F6, 0xA3509CFF5B01D17C, 0xBD870219DBDE553D, 0xC24847905D600F2, 0x3F6029BE326908F1, 0x956902BB0608AF31, 0x19FBAFFCD},
{0x43909A8B57B3D387, 0x11CAD4DD5E94732, 0x5ACD10DE50BD4786, 0xA485CF553F041B2F, 0x78621C881B370A7F, 0x54D76CE547ACAC13, 0xD2BAF160F13C3B9E, 0x4FDE5E64A3480204, 0x2501DA6825E2CC9A, 0xD63111F9}
};
static const uint64_t table_v_qnr[TABLE_V_LEN][NWORDS64_FIELD] =
{{0xAD4AD4AD4C6A88FF, 0x4AD4AD4AD4AD4AD4, 0xD4AD4AD4AD4AD4AD, 0xAD4AD4AD4AD4AD4A, 0xA6D6AD4AD4AD4AD4, 0x9AEFF6AA14208728, 0x25F686D3A6B965DD, 0x89CFD24F7B8B05D6, 0x3277900023742A0A, 0x181A60983},
{0x95A95A959CABB803, 0xA95A95A95A95A95A, 0x5A95A95A95A95A95, 0x95A95A95A95A95A9, 0xEF5495A95A95A95A, 0x9FD9D03AB2C137A2, 0xD6D285BBE104B16D, 0x2D2DEC66777C8B23, 0xF413D3CA7DE5EA6B, 0x5EA0F8F0},
{0x890EF755DC154E99, 0xA890EF755DBC422A, 0x2A890EF755DBC422, 0x22A890EF755DBC42, 0xE6F8890EF755DBC4, 0x992CEA18AE912E4D, 0x78C13445EFF8450A, 0xFC7F0B40B903DCD5, 0x3DEB2380F4A72BD3, 0x14B83DE77},
{0x5CF29BF686807934, 0x25CF29BF68C35902, 0x25CF29BF68C3590, 0x9025CF29BF68C359, 0xE9A5CF29BF68C35, 0x298A955A6155A056, 0x8F77CBC74E2AE5F6, 0x366A3337A563ECA7, 0xB5182885FF4D6097, 0x1885CE5B2},
{0x1060A07FBF2642F, 0xE01060A07FBE7D7E, 0x7E01060A07FBE7D7, 0xD7E01060A07FBE7D, 0x832001060A07FBE7, 0xED7D83B8855A105B, 0x61124019E05FD124, 0x17593771A74013B3, 0x65ED650971772921, 0x27986C521},
{0xCCD20A70CAA86EA0, 0x3CCD20A70CCB7D63, 0x63CCD20A70CCB7D6, 0xD63CCD20A70CCB7D, 0xE023CCD20A70CCB7, 0x46FB7D673A1F3731, 0x4BB2D66D1167EA52, 0x455020A49BCB6949, 0x65C58A1BD6024304, 0x79DA31E3},
{0xC8A714319269CBF, 0x3EE6C5324FB03682, 0x820C8A7143192186, 0x863EE6C5324FB036, 0xEB040C8A71431921, 0x136A320C0C040BB6, 0x168E5DED014E95FF, 0x823E3A98411D42EC, 0xBF3B909BE84CA071, 0x20313C368},
{0x79102520ED23EA0D, 0x4F1889D99670AB6C, 0x6C79102520EE923E, 0x3E4F1889D99670AB, 0x415279102520EE92, 0x70DBE13BE1C34F41, 0x5B5EAA3FAF145AD4, 0x783FC4CF8CF9BE6B, 0x137330EF8AE1C880, 0x1B4499FA0},
{0x4634145CDBBC7D65, 0xBE4634145CDBB9BE, 0xB9BE4634145CDBB9, 0xDBB9BE4634145CDB, 0xFC11B9BE4634145C, 0x2FE8FEBF758B8693, 0x62828E9265ECF9A0, 0x1C4ED813B3BC7207, 0x846F272559B2E04B, 0xB0BF2182},
{0x20103473E1D7FF3A, 0x2920103473E2E529, 0xE52920103473E2E5, 0xE2E52920103473E2, 0x896EE52920103473, 0x11F70027A281C06D, 0x3B5E57817B07BF75, 0xAB30DBCF075069D5, 0x7934D8F49EE1D2A2, 0x1E5CF7B77},
{0x9A1999347725E051, 0x99B2E2369C46A0F7, 0x477258EE57C21979, 0x69C46A0F79A19993, 0x56DA2197999B2E23, 0xCE319B8B5D5BF252, 0x5FFDE836E4511966, 0x3C4EE6DEE16E12B3, 0xF9D395517385C677, 0xC56DA3A3},
{0xA333A4F9F563A486, 0x16C18290308AE972, 0x9F5BF3DD45A35733, 0x308AE972A333A4F, 0xF74E3573316C1829, 0x6C7C6702DC7153B0, 0x77D40082BF6132B4, 0xD95D312C4920072E, 0x7E9DE8AED502DB52, 0x1795EC244},
{0xBFAD90149BFAF2C4, 0xAD90149BFAD90149, 0x90149BFAD90149BF, 0x149BFAD90149BFAD, 0x7E72D90149BFAD90, 0x6866E05B5982496, 0xC0A9956428181AA3, 0x692DDBE0498CF749, 0x8D9D8E6C9C0C1C9F, 0x123FACCAD},
{0xA4DFD6C80A1A7714, 0xDFD6C80A4DFD6C80, 0xD6C80A4DFD6C80A4, 0xC80A4DFD6C80A4DF, 0x8425FD6C80A4DFD6, 0x8E0BC711DB513DD0, 0x7A798B500484E43A, 0xB493DF45AE3AFC5, 0x35B299EB698262E2, 0x251C8F93C},
{0xF106BA2361C0BBFC, 0x267751BCCB188710, 0xCF04E54D6488BC95, 0xE9C02260C68B4DBC, 0xA0F2D5B56BFB777B, 0xC62C2D54EEB3DD6D, 0x8C3B7A47FF6C7E8D, 0xE7AD379C550443FF, 0xE820CAF499D9CD06, 0xBB9BA44B},
{0xCECFBC1D4AD7905D, 0x269973BD729F0BBF, 0x96F247430346373F, 0x3C32617FB97A7BB4, 0x170F7C62323C3A3A, 0x1B9DB0A6D879BD7E, 0xDA82AC8B59360996, 0xA26FE113F634C7A, 0x7130F589581CBC64, 0x13858DF6C},
{0x7E5D2D52571E03D0, 0xF75D1072B445F79B, 0x706331C41D88D1D5, 0x265B33A4D24975E8, 0xC97488655D632ABE, 0x6D82AC11CD7F6048, 0xB030079E0A9EBAD4, 0xA7E87B1B62EAFB16, 0x9522F6F141D35D44, 0x82B24B60},
{0x242547937C0658FA, 0xDC6E5DA7AEE53E68, 0x84EA07953DACDA65, 0xE92546CBB60D8BA3, 0xA612BF6B9CFBCEAE, 0xB2353AB9010C800F, 0x1BBAD6158193C629, 0x5464119263DFE2DF, 0x50E7B308405743DC, 0x20FCCD43A},
{0x6D72564707F57DA7, 0x44E62AEA7A94D72F, 0xC60D55CE4D3ABF28, 0xC819D3C0BC081DE5, 0x161317D2034B91E3, 0x9A84FE10A373C3D5, 0xD73276492F6D4036, 0x5332ED7A2830AE9E, 0xCC28BE76FB2DF00A, 0x120CA3CCB},
{0xFAB2620720D754B4, 0xB0B9E340EEDF8BC9, 0x1653DB4EA86AA228, 0xAF4A45B466A291F5, 0x6F2D8FB5B3D8182E, 0x7774D2D36F2E881F, 0xC3D2516E474E557D, 0x92B45DD23EC32833, 0x3984A07B8619C7C9, 0x1CAB80BBA},
{0xE7CC90E6EE298EA, 0x99D3392BBC06C468, 0xE8F51B6B2D8C36DD, 0x7477C602BFC793C0, 0x4CC9A5B9824BBB8D, 0x66B8B5F5427D3453, 0xCC9FA954AA043A0, 0xE68FEBFA58A0024E, 0x1C4E709FC346F24B, 0xE0867832},
{0x16134C45F74D2894, 0x645075230AF517E, 0x638788BD12EAF884, 0xBB57CA874264F15D, 0x83B306DD1713D2A4, 0x623C0C908B287197, 0xBA8FC5C2734F4A9E, 0xFC971C3F17C55B04, 0x61546665082121F8, 0x18551EAB8},
{0x47236352CCCCD4B, 0x807700F6D1EDDCEE, 0x17537341BAEA6CBA, 0x504419A64B50C73D, 0x2591E7171ACC64DE, 0xEB04A5C122391E85, 0xD96557BF89D24F8E, 0x780CD38FF64726CB, 0xFDAFF780CC4EB54E, 0x11861577},
{0x302306EE9997BC4D, 0x3E045AB634949BFF, 0xCC742F753994DECA, 0x7E7F0333368EA0FF, 0x8A8430A2AB229760, 0xE1D75408F952D6F, 0x4F3D600657F280B3, 0xDE89E80487A538B0, 0x68D1E57A19D64620, 0xD0027A4E},
{0x5970FB914A91F4D4, 0xEF97BEC7A9F0D144, 0x693EE802E571FE58, 0xCE320E8569E81BC7, 0x2FE521976533C96E, 0xE5D7F9268E7D0519, 0xFAFD246C31C4833, 0x7218544447E13899, 0xEA1FFC738CF3C5D3, 0x95EB5BCC},
{0x5B105189D0CA2ADE, 0xCEDD8AD3AABF2386, 0xA052407BEE2D471, 0xD51FFCA04EBD31DF, 0x7CFF2C4FBFF9840F, 0x68E863DD7BE0FB3F, 0x71ADC0F419B76B2F, 0x9F2486034EC06308, 0xEE7F083774F1E588, 0x1782E172E},
{0x26B06F653E426CA3, 0x653E426B06F653E4, 0x6B06F653E426B06F, 0x53E426B06F653E42, 0xCD29653E426B06F6, 0xE25934934CDB47A9, 0x368EE07F45083838, 0xFF81E126E2784509, 0xB7FBA2C6FB2C0307, 0x66F35905},
{0x7C84D60DEC9AE6B4, 0xDECA7C84D60DECA, 0xC84D60DECA7C84D6, 0xDECA7C84D60DECA7, 0x5F6E0DECA7C84D60, 0x5E606F56135F2DCD, 0x6D881359A8F60397, 0x381AE539FC37E98C, 0x29BF8428D894967B, 0x12918EDC8},
{0xBF924F1BF0EB7ADA, 0xC78EDA5EA1CEF780, 0x48C247D7D53CFE2, 0x3FE9A831F3E25AF8, 0xC4223C70A27E8F90, 0x51DCF86B78B6D4C0, 0x29A14DBF09A8A42, 0x35B0B186FFA03AA9, 0xB34DDE1D41C9D131, 0xF56A46E3},
{0x253AF4484C94CA03, 0x32A226E35D2A4AA2, 0x4FB18C5BBCF1589A, 0x3E17070314360DE9, 0xB94BC9B9873E96C0, 0x8A3E6EFEA06EB882, 0xC06DE286FA2EECCD, 0x124298F6432B070E, 0x25CB59755BA0A18B, 0x14B1CD916},
{0xBF83218A8CCC3E78, 0x5BD5A5F17E801598, 0x2F948F576364D3E7, 0xF9D2270EC3408B6F, 0xC00D05257D2C78BC, 0x3CA32AC0114D7EAF, 0x16D9296AC7B7D2D4, 0x6E661F03BA457337, 0x3F69FD67E3F62F31, 0xA70AFB41},
{0x67B914B86B6BD1E0, 0x9E7D53018B3CF47E, 0x4A5172C659663E8A, 0xCE0F42ACA114BBDA, 0xCF29856D865D954F, 0xDC1EF1F853824B06, 0x8D28378F21C8EB01, 0x8140F83D8E9FBBA9, 0xEF3B3FBF4817BA, 0x1CEA072EF},
{0xB04ACFA73EA0C46C, 0xCF933F68BB9B3F4A, 0x15AE5CE2F27DB04C, 0x1695B1823A1F6D59, 0xD753A316CA51CB6, 0x7445E2D99B0BA50B, 0xB6F9A9A580E786, 0x51545996DACD4F17, 0x112B452323F4F0A3, 0xAFBF4B5F},
{0xA8982A5E43B37B3, 0x4D1DFB947C1F2BC7, 0x7A938628C766F64A, 0x545AB97381CCDA04, 0xD8ACCB93F83D4C5B, 0xCA5959634A186221, 0x9E72DEA20E161486, 0x3FB2EF9969B4F6C, 0xA62EC7356550C78, 0x1C0F7BD25}};
static const uint64_t table_v_qnr[TABLE_V_LEN][NWORDS64_FIELD] = {
{0xAD4AD4AD4C6A88FF, 0x4AD4AD4AD4AD4AD4, 0xD4AD4AD4AD4AD4AD, 0xAD4AD4AD4AD4AD4A, 0xA6D6AD4AD4AD4AD4, 0x9AEFF6AA14208728, 0x25F686D3A6B965DD, 0x89CFD24F7B8B05D6, 0x3277900023742A0A, 0x181A60983},
{0x95A95A959CABB803, 0xA95A95A95A95A95A, 0x5A95A95A95A95A95, 0x95A95A95A95A95A9, 0xEF5495A95A95A95A, 0x9FD9D03AB2C137A2, 0xD6D285BBE104B16D, 0x2D2DEC66777C8B23, 0xF413D3CA7DE5EA6B, 0x5EA0F8F0},
{0x890EF755DC154E99, 0xA890EF755DBC422A, 0x2A890EF755DBC422, 0x22A890EF755DBC42, 0xE6F8890EF755DBC4, 0x992CEA18AE912E4D, 0x78C13445EFF8450A, 0xFC7F0B40B903DCD5, 0x3DEB2380F4A72BD3, 0x14B83DE77},
{0x5CF29BF686807934, 0x25CF29BF68C35902, 0x25CF29BF68C3590, 0x9025CF29BF68C359, 0xE9A5CF29BF68C35, 0x298A955A6155A056, 0x8F77CBC74E2AE5F6, 0x366A3337A563ECA7, 0xB5182885FF4D6097, 0x1885CE5B2},
{0x1060A07FBF2642F, 0xE01060A07FBE7D7E, 0x7E01060A07FBE7D7, 0xD7E01060A07FBE7D, 0x832001060A07FBE7, 0xED7D83B8855A105B, 0x61124019E05FD124, 0x17593771A74013B3, 0x65ED650971772921, 0x27986C521},
{0xCCD20A70CAA86EA0, 0x3CCD20A70CCB7D63, 0x63CCD20A70CCB7D6, 0xD63CCD20A70CCB7D, 0xE023CCD20A70CCB7, 0x46FB7D673A1F3731, 0x4BB2D66D1167EA52, 0x455020A49BCB6949, 0x65C58A1BD6024304, 0x79DA31E3},
{0xC8A714319269CBF, 0x3EE6C5324FB03682, 0x820C8A7143192186, 0x863EE6C5324FB036, 0xEB040C8A71431921, 0x136A320C0C040BB6, 0x168E5DED014E95FF, 0x823E3A98411D42EC, 0xBF3B909BE84CA071, 0x20313C368},
{0x79102520ED23EA0D, 0x4F1889D99670AB6C, 0x6C79102520EE923E, 0x3E4F1889D99670AB, 0x415279102520EE92, 0x70DBE13BE1C34F41, 0x5B5EAA3FAF145AD4, 0x783FC4CF8CF9BE6B, 0x137330EF8AE1C880, 0x1B4499FA0},
{0x4634145CDBBC7D65, 0xBE4634145CDBB9BE, 0xB9BE4634145CDBB9, 0xDBB9BE4634145CDB, 0xFC11B9BE4634145C, 0x2FE8FEBF758B8693, 0x62828E9265ECF9A0, 0x1C4ED813B3BC7207, 0x846F272559B2E04B, 0xB0BF2182},
{0x20103473E1D7FF3A, 0x2920103473E2E529, 0xE52920103473E2E5, 0xE2E52920103473E2, 0x896EE52920103473, 0x11F70027A281C06D, 0x3B5E57817B07BF75, 0xAB30DBCF075069D5, 0x7934D8F49EE1D2A2, 0x1E5CF7B77},
{0x9A1999347725E051, 0x99B2E2369C46A0F7, 0x477258EE57C21979, 0x69C46A0F79A19993, 0x56DA2197999B2E23, 0xCE319B8B5D5BF252, 0x5FFDE836E4511966, 0x3C4EE6DEE16E12B3, 0xF9D395517385C677, 0xC56DA3A3},
{0xA333A4F9F563A486, 0x16C18290308AE972, 0x9F5BF3DD45A35733, 0x308AE972A333A4F, 0xF74E3573316C1829, 0x6C7C6702DC7153B0, 0x77D40082BF6132B4, 0xD95D312C4920072E, 0x7E9DE8AED502DB52, 0x1795EC244},
{0xBFAD90149BFAF2C4, 0xAD90149BFAD90149, 0x90149BFAD90149BF, 0x149BFAD90149BFAD, 0x7E72D90149BFAD90, 0x6866E05B5982496, 0xC0A9956428181AA3, 0x692DDBE0498CF749, 0x8D9D8E6C9C0C1C9F, 0x123FACCAD},
{0xA4DFD6C80A1A7714, 0xDFD6C80A4DFD6C80, 0xD6C80A4DFD6C80A4, 0xC80A4DFD6C80A4DF, 0x8425FD6C80A4DFD6, 0x8E0BC711DB513DD0, 0x7A798B500484E43A, 0xB493DF45AE3AFC5, 0x35B299EB698262E2, 0x251C8F93C},
{0xF106BA2361C0BBFC, 0x267751BCCB188710, 0xCF04E54D6488BC95, 0xE9C02260C68B4DBC, 0xA0F2D5B56BFB777B, 0xC62C2D54EEB3DD6D, 0x8C3B7A47FF6C7E8D, 0xE7AD379C550443FF, 0xE820CAF499D9CD06, 0xBB9BA44B},
{0xCECFBC1D4AD7905D, 0x269973BD729F0BBF, 0x96F247430346373F, 0x3C32617FB97A7BB4, 0x170F7C62323C3A3A, 0x1B9DB0A6D879BD7E, 0xDA82AC8B59360996, 0xA26FE113F634C7A, 0x7130F589581CBC64, 0x13858DF6C},
{0x7E5D2D52571E03D0, 0xF75D1072B445F79B, 0x706331C41D88D1D5, 0x265B33A4D24975E8, 0xC97488655D632ABE, 0x6D82AC11CD7F6048, 0xB030079E0A9EBAD4, 0xA7E87B1B62EAFB16, 0x9522F6F141D35D44, 0x82B24B60},
{0x242547937C0658FA, 0xDC6E5DA7AEE53E68, 0x84EA07953DACDA65, 0xE92546CBB60D8BA3, 0xA612BF6B9CFBCEAE, 0xB2353AB9010C800F, 0x1BBAD6158193C629, 0x5464119263DFE2DF, 0x50E7B308405743DC, 0x20FCCD43A},
{0x6D72564707F57DA7, 0x44E62AEA7A94D72F, 0xC60D55CE4D3ABF28, 0xC819D3C0BC081DE5, 0x161317D2034B91E3, 0x9A84FE10A373C3D5, 0xD73276492F6D4036, 0x5332ED7A2830AE9E, 0xCC28BE76FB2DF00A, 0x120CA3CCB},
{0xFAB2620720D754B4, 0xB0B9E340EEDF8BC9, 0x1653DB4EA86AA228, 0xAF4A45B466A291F5, 0x6F2D8FB5B3D8182E, 0x7774D2D36F2E881F, 0xC3D2516E474E557D, 0x92B45DD23EC32833, 0x3984A07B8619C7C9, 0x1CAB80BBA},
{0xE7CC90E6EE298EA, 0x99D3392BBC06C468, 0xE8F51B6B2D8C36DD, 0x7477C602BFC793C0, 0x4CC9A5B9824BBB8D, 0x66B8B5F5427D3453, 0xCC9FA954AA043A0, 0xE68FEBFA58A0024E, 0x1C4E709FC346F24B, 0xE0867832},
{0x16134C45F74D2894, 0x645075230AF517E, 0x638788BD12EAF884, 0xBB57CA874264F15D, 0x83B306DD1713D2A4, 0x623C0C908B287197, 0xBA8FC5C2734F4A9E, 0xFC971C3F17C55B04, 0x61546665082121F8, 0x18551EAB8},
{0x47236352CCCCD4B, 0x807700F6D1EDDCEE, 0x17537341BAEA6CBA, 0x504419A64B50C73D, 0x2591E7171ACC64DE, 0xEB04A5C122391E85, 0xD96557BF89D24F8E, 0x780CD38FF64726CB, 0xFDAFF780CC4EB54E, 0x11861577},
{0x302306EE9997BC4D, 0x3E045AB634949BFF, 0xCC742F753994DECA, 0x7E7F0333368EA0FF, 0x8A8430A2AB229760, 0xE1D75408F952D6F, 0x4F3D600657F280B3, 0xDE89E80487A538B0, 0x68D1E57A19D64620, 0xD0027A4E},
{0x5970FB914A91F4D4, 0xEF97BEC7A9F0D144, 0x693EE802E571FE58, 0xCE320E8569E81BC7, 0x2FE521976533C96E, 0xE5D7F9268E7D0519, 0xFAFD246C31C4833, 0x7218544447E13899, 0xEA1FFC738CF3C5D3, 0x95EB5BCC},
{0x5B105189D0CA2ADE, 0xCEDD8AD3AABF2386, 0xA052407BEE2D471, 0xD51FFCA04EBD31DF, 0x7CFF2C4FBFF9840F, 0x68E863DD7BE0FB3F, 0x71ADC0F419B76B2F, 0x9F2486034EC06308, 0xEE7F083774F1E588, 0x1782E172E},
{0x26B06F653E426CA3, 0x653E426B06F653E4, 0x6B06F653E426B06F, 0x53E426B06F653E42, 0xCD29653E426B06F6, 0xE25934934CDB47A9, 0x368EE07F45083838, 0xFF81E126E2784509, 0xB7FBA2C6FB2C0307, 0x66F35905},
{0x7C84D60DEC9AE6B4, 0xDECA7C84D60DECA, 0xC84D60DECA7C84D6, 0xDECA7C84D60DECA7, 0x5F6E0DECA7C84D60, 0x5E606F56135F2DCD, 0x6D881359A8F60397, 0x381AE539FC37E98C, 0x29BF8428D894967B, 0x12918EDC8},
{0xBF924F1BF0EB7ADA, 0xC78EDA5EA1CEF780, 0x48C247D7D53CFE2, 0x3FE9A831F3E25AF8, 0xC4223C70A27E8F90, 0x51DCF86B78B6D4C0, 0x29A14DBF09A8A42, 0x35B0B186FFA03AA9, 0xB34DDE1D41C9D131, 0xF56A46E3},
{0x253AF4484C94CA03, 0x32A226E35D2A4AA2, 0x4FB18C5BBCF1589A, 0x3E17070314360DE9, 0xB94BC9B9873E96C0, 0x8A3E6EFEA06EB882, 0xC06DE286FA2EECCD, 0x124298F6432B070E, 0x25CB59755BA0A18B, 0x14B1CD916},
{0xBF83218A8CCC3E78, 0x5BD5A5F17E801598, 0x2F948F576364D3E7, 0xF9D2270EC3408B6F, 0xC00D05257D2C78BC, 0x3CA32AC0114D7EAF, 0x16D9296AC7B7D2D4, 0x6E661F03BA457337, 0x3F69FD67E3F62F31, 0xA70AFB41},
{0x67B914B86B6BD1E0, 0x9E7D53018B3CF47E, 0x4A5172C659663E8A, 0xCE0F42ACA114BBDA, 0xCF29856D865D954F, 0xDC1EF1F853824B06, 0x8D28378F21C8EB01, 0x8140F83D8E9FBBA9, 0xEF3B3FBF4817BA, 0x1CEA072EF},
{0xB04ACFA73EA0C46C, 0xCF933F68BB9B3F4A, 0x15AE5CE2F27DB04C, 0x1695B1823A1F6D59, 0xD753A316CA51CB6, 0x7445E2D99B0BA50B, 0xB6F9A9A580E786, 0x51545996DACD4F17, 0x112B452323F4F0A3, 0xAFBF4B5F},
{0xA8982A5E43B37B3, 0x4D1DFB947C1F2BC7, 0x7A938628C766F64A, 0x545AB97381CCDA04, 0xD8ACCB93F83D4C5B, 0xCA5959634A186221, 0x9E72DEA20E161486, 0x3FB2EF9969B4F6C, 0xA62EC7356550C78, 0x1C0F7BD25}
};
static const uint64_t v_3_torsion[20][2 * NWORDS64_FIELD] =
{{0x6EB3E454124AAF4, 0xEB3E45306EB3E453, 0x3E45306EB3E45306, 0x45306EB3E45306EB, 0x286B3E45306EB3E, 0x375E62F5BC7C82AF, 0x650BCBF202B9AE38, 0x3FDD465F450DFCFD, 0xC63A99445C986900, 0x250ED785C, 0x2983759F1FCF38D7, 0x83759F22983759F2, 0x759F22983759F229, 0x9F22983759F22983, 0x4EEA3759F2298375, 0x87430979EEB424F2, 0x4D75F319566660DA, 0x30CD05437A146239, 0xA2641600BDE8C04, 0x712AA3BE},
{0xCF43C7FB897F2FE2, 0x3C7FB84C2F0E011E, 0xFB84C2F0E011ECF4, 0x4C2F0E011ECF43C7, 0x751C11ECF43C7FB8, 0x1D007C113B5D095, 0x4235B0D5E66773CE, 0x9E42B6C94350F39E, 0xB98F10656ABF493B, 0xA2738C79, 0xC023D9E87818892A, 0x3D9E878FF70985E1, 0xE878FF70985E1C02, 0x8FF70985E1C023D9, 0x52445E1C023D9E87, 0xC4A56A1DB3037852, 0xBE1F9B0F8C463146, 0xD7DB04211C8A255B, 0x87C4C4B67CF93C1C, 0x96C2BFBD},
{0xBB5E4448409D1B64, 0x9650668A321ACCD8, 0x48D39ADBC2F1339E, 0x8F7071B9DA7AD093, 0xDC2BFF88AE51552D, 0x67B12046E4504FA2, 0xDAC40568A6E7ACA6, 0x62ACCE83A2BE7FE7, 0xCEBB880D5DC0D19E, 0x25FA2A502, 0x12FE408DB093593F, 0xAAF044FB38FAC1A9, 0x2726CD500D0CEF1, 0x1605D37D0757467F, 0x1B66F6542117A77, 0x1350C0D1B1A7435E, 0x51F0069F69135871, 0x203791450029A4BC, 0x42B7E3FCB870BE19, 0x1CDC6F300},
{0x7B5CB802B56792C7, 0xBD1E27BB33DC664B, 0xC2399B484A347FD4, 0x5CB802B42E1D844C, 0x7699BB33DC664B7B, 0xA62220120D0CB91A, 0x24AAF6ED9C3527F0, 0x1FA962A3FE0A08F3, 0x219A48CC422DF1B1, 0x118AF1785, 0x2085638DAFEB8A83, 0xFD68A923B68BC5DE, 0x9743A21DF7A9C724, 0x85638DB029756DC4, 0x9A323B68BC5DE20, 0xDC5A0F3CC5799C18, 0x3CDBDDF993C3E933, 0x399816785890182E, 0x3DDF5FEAA7F4990C, 0xAC3F3421},
{0x63BDA9468BD342F5, 0x7403E8DA50E41EF7, 0x7B32C72BE3C39E62, 0xA4AEF030E69A6DAF, 0xC8E9EC938255BB45, 0x5AE36274AC3BB919, 0xAF73A8FEA01C6E98, 0x6C9E0C391AEA075A, 0xDE3F1DFEA825A09A, 0x495C0A99, 0xCDBBE48241B79B59, 0x29FF396B0854C507, 0xC91466B43E7DC219, 0xA46772E1FAE15C03, 0xC113B29586A5D8CF, 0x44FE6A6E5B9FB7B0, 0x11825F97D892585E, 0xC1F3209A0E0006B4, 0x313425C4139E19C4, 0x14DB5D37A},
{0x3011EB8A0C610EAE, 0x8632968FCBEC6D1D, 0xEF749BB7DE6283EB, 0x1038A58CDB855B10, 0x5574052BEBB46182, 0xB3E1CF3C83597C0F, 0xA718ADD06AD56610, 0x359FB5AA447520F6, 0xCDF6E662B8EB669C, 0x9CC50ACC, 0x4E213592827CF602, 0xB80C916F6BF2EBB6, 0xD05F9D238FE11743, 0x5FC7793D16D042BF, 0xBD58FD8E99F594EA, 0xC1100B4C07C4A897, 0x29F16A0996A54969, 0x3A7EB43A7FC5530D, 0xB3EF41DC7BE3CE6C, 0x4A3A4407},
{0x32CEC987C02E1E16, 0xB7E44C9BBD497EE5, 0x59C0313782E83DF1, 0x2C71AF09B871F5DE, 0xE44DFBF49F9CEA51, 0xC4BD0DF1CC341EB3, 0x7EC7C21EE53DE39D, 0x2B1B1BB9C6276C2C, 0xF86DE3A5ABE9539E, 0x2302FFE8B, 0x28DF22C8DCD7982F, 0x426541E94DCF04E7, 0x98CA1BA8F9B2855A, 0xF4067E6F7EA49E1D, 0xD03034D68F095472, 0x7D26821B325A3A85, 0x87DB2B11EC3322D6, 0x73BAAA33C117FB57, 0x92225964AC014B47, 0x12E0D7FE7},
{0xDF2479A490E3F3DA, 0xE07894F7FF684C36, 0x9A5E7229EF62380A, 0xE88DF8EE954C69A4, 0x800A8000EAE4D453, 0xAE77A73EF2BD6B7D, 0xDA18723BBC2CA8D7, 0xF186FA30727D2A31, 0x291452F619104C5B, 0x1E7F1399, 0x3732F21D651B1FEE, 0x8DDCCB2BDD071E43, 0x9641B49A54A8A116, 0xDA68148CA4D341DD, 0xC32B7A049A23B8F4, 0x24932D3124EB482F, 0x84AE00B5C46870B9, 0xCEAE14C3C3D55562, 0x97148EC2C4193A5, 0x1D94CB43},
{0x5DDBBCF90B937BD9, 0x3E84379AA3442E8, 0xCC25DC2808E0C528, 0xFB444A0D98465DEB, 0xD69F5A96BE71AC2C, 0x13938F1D6E581318, 0x37AE0B4F7DAC04ED, 0x863F2AD318BF5A7F, 0x397673E27BAC9DEA, 0x1216A9621, 0x904B65B8E15A658, 0xC7BB97BD7B0C45E2, 0x93CD91DECA863B07, 0x7E159E553BF8497, 0x5075FEF394A53914, 0xE7E384970BABE75A, 0x5968B82EF98ECFC6, 0x29B5FE78CEF214F8, 0xE3F63B7F9DF9725C, 0xFDF9B378},
{0x57CC8084740AF239, 0x5703E093ED1DEC26, 0x700B10597FE6838D, 0xBDADB8A8DE7E5988, 0x3EEB9E3F634109D8, 0xC632284A295D87A2, 0xFF7ED47380421F0, 0x46A42D85372D6D51, 0xCEB02C53FD6561AD, 0x68700397, 0x94083C312FDD1CCF, 0x8D8BBEBC2683FDD4, 0xDF6AA14583575AC1, 0xDF3FF19FF44AEEA3, 0xCEBEB4FB032ECD7D, 0x9CE783658636286, 0x7B3D4444C53B3D32, 0xB8749FA7F3A9070, 0xC415DCDB6A0AD61E, 0xB7869319},
{0x139CF42869D49482, 0xBC6F0C720A8973B, 0x28E407583814A9E0, 0xF00EFBF2ED7F95AF, 0x7D480A57AEF5BFD3, 0x7EC46EDF97D9EAC2, 0xB3F987339979273B, 0x699F07E12CA4729D, 0x7A1D6F1D94D877DD, 0x24F8BFBDA, 0x971EC29363AFF4EF, 0xA525D0504E28FD9, 0xB1499925B9A9134F, 0x3790DCE6BA9C9907, 0x9E2EB2BD7D2BDE58, 0xB1A37E98CE909692, 0x4C9EB9AB58C0D4A9, 0x77A16CF26A2492C6, 0xB2121E58A818AFB2, 0x5FF8FB81},
{0xD59C657588B26B4C, 0xB824E399449753E5, 0xB2EA59D067504894, 0x2E77C98265BE8415, 0x3A34AD15D89E7895, 0x6AA2E3EAB0F65905, 0x3A464491A81B6AD6, 0x64AFCC145F1EE37C, 0xEF30841D92867D4C, 0x1653C11AC, 0xC4A62DC72662944A, 0x4BC6EC7683E05B2E, 0xDE0AB70705491613, 0x7FC5FD6400FBAE3A, 0xBE093F12B7441F4E, 0x754D61F85BE9B748, 0xED144F4AD57B89A0, 0x4B6DFB51DECE2551, 0x67980426FCD240D0, 0x75699852},
{0xD3D4BB413D7061BE, 0x18AEC9D6854ECB25, 0x74912785EEF65EF3, 0x428B21B602840579, 0x7BEDFBC19961AB28, 0xE537045DFA2E6F0C, 0xAF709EC9946F55BB, 0xD4633E3CA2BBFE3D, 0xDDF84B965ACD8170, 0x1837A2775, 0xFB8249F345205225, 0xDC81B2C34B0B30FC, 0xF5B9D98AC4766CBA, 0x8B37B96AC565EDF5, 0xAB88EC455AB3E730, 0xF99410A2815AE199, 0x926C8A85493EB093, 0xC7082D622A51444B, 0xFE11910D6EC752C1, 0x22D0E6336},
{0xFBDC842A96D96B13, 0xEE3034ABA5D2EC9A, 0x5D4BFE83ECA3D306, 0x10CE1C3DB0210EC, 0x645EB45E9AC10E46, 0x99085D8D171BC2BE, 0x9F361AF1FC456B18, 0x8D9D38D8C416A25, 0xB071C0B7D59CE33C, 0xD89DA6CB, 0x770A7B6239055C1F, 0xE9767FC8D42B73D3, 0xFCC1954DC3AC1EE7, 0x1251746D17D4CA40, 0xD83FEEE6736971D, 0xB0210B1F8D0AB262, 0x3DE49D676CD13FB7, 0x1657FEBB10C212AF, 0x2F61A2D8A3F81312, 0x18E3342F8},
{0xD08AB92DAE048DB1, 0xAFDFB841D45B6CDB, 0x4E16B9F649DBDAD4, 0x8F7BD80A86CD6FE4, 0xE9D860EE31368282, 0xAB87FA97EF9B4B4E, 0x595B5FD6D5CD3C22, 0x8B2AF45E9CDA91B3, 0x2DFE5B32A817912D, 0x1FB079EE, 0x6B3EC443091B482D, 0x9248D66829014899, 0x638D81CC4AE199D, 0x5E8DE73EEB6DE96A, 0x55771848724D17F0, 0x734CB651B4339600, 0xFD2432CB79D99C1B, 0x373869CEA55DDEC4, 0x39D83CB6F4815AF5, 0xD31D84E9},
{0x8FC08908D008677E, 0xF50D53E90F7118D4, 0x38984342BC5C5F12, 0x9EF8ADEE9D890053, 0x2E9134B510F28488, 0x8951AC1CA56CA72C, 0x7CFED4FEED36EDEC, 0xCDF3038414AC384C, 0xA2C3889B433C8C6F, 0x27A01960F, 0xA3526DB518930119, 0xDC37B0E13644ED3F, 0x6E31E890F08A37BD, 0xA37A5E57024A8AA0, 0x40B194BE09CD892F, 0xF8D9FD2F6BFCA6BD, 0x20DFBAEF4B42549B, 0x45F0B1D7FBC11721, 0x5E7E3BB644063BE0, 0x171428956},
{0xB637BBC305F67791, 0x204FF0D2AEDF672E, 0xF92D3782494289DB, 0x24F7EB7320299A80, 0x977CC127123CD922, 0xB6C51C2947B68DB4, 0xBEFC8E5B0AE18F09, 0xFABDF4A65AAD3791, 0xAEBB5AA66A4EC660, 0x9F9CF17F, 0x110C3AF5E13E1951, 0xF40DC401CC686B06, 0x68EEA45A46B10505, 0x325395A25A0F0DE9, 0x1C92E56F56D28E24, 0xD0F8A55787894E1F, 0xEEEC7393357C5523, 0x5FB696B3518CC792, 0xD39D05F3A9382E5A, 0x26B74CDB1},
{0xBDF8A208F713F4A9, 0x18481280856177D9, 0x10BD738108662F2C, 0x1EF37C1AB5531600, 0x98D3C52040B3E9DB, 0x8E988D26C011FF69, 0x18AE98AA255688B, 0x8E60CDC1B136648B, 0x7E91BFE825833F56, 0x13DB93F4A, 0xC90DED2C7313B98, 0x82F6CE5855C8D3AC, 0xD22BF07E7380D124, 0xE912C49BBF549FD8, 0xBD34790D9C351C45, 0x4A1A372896AB66BF, 0x44E6AD3D3CB7D968, 0x473B9962DF10B605, 0x2DC4E87221525887, 0xD61465},
{0x3E77A9B726C4E35A, 0x72508865383E24E9, 0x703A850A1795B24B, 0xB744F39B78F82E6, 0xBCA3D4CB44C8DE88, 0x98BB9A1523EDC1A1, 0x1055B9EF0ED241A1, 0xDF619C4A7A3305B, 0xD3CAD19AFBE71CE8, 0x8A810A03, 0x78553A5AD2AFD1FC, 0x87C486E5D053F7C5, 0xD49A2C8D3988259, 0xD059B9BB567D1CB1, 0x5D10F35FBB64BF63, 0xB6A58DE0F78BF9DD, 0xCD0DEBAFEA4B0478, 0xDAF46A0964D3FD0A, 0x8E33C74FE2F70AFC, 0x21CAAD2F8},
{0x3BABE989C4B7C8C6, 0x2BF8F447EF3BDD7D, 0x20EAAD8C5457CF18, 0x8C176F27BA3E5B6D, 0x6994DF1010BAB10B, 0xC508E30E46C0CA1E, 0xA48AA3C16405257B, 0xFDA00D371BEC4681, 0x9D86B52EDF6EC9F8, 0x1C34BB8B6, 0xADB4F379816C780A, 0xC25F504173CEACF5, 0x1DA0375FEB0BBE8C, 0xB87264B37860585, 0xE0E1B8080C0215AB, 0xA4E2CD906374B7FC, 0x5326260B7A3021ED, 0x168C806A9FD020B4, 0xDD2E356F2066C037, 0x110BD582B}};
static const uint64_t v_3_torsion[20][2 * NWORDS64_FIELD] = {
{0x6EB3E454124AAF4, 0xEB3E45306EB3E453, 0x3E45306EB3E45306, 0x45306EB3E45306EB, 0x286B3E45306EB3E, 0x375E62F5BC7C82AF, 0x650BCBF202B9AE38, 0x3FDD465F450DFCFD, 0xC63A99445C986900, 0x250ED785C, 0x2983759F1FCF38D7, 0x83759F22983759F2, 0x759F22983759F229, 0x9F22983759F22983, 0x4EEA3759F2298375, 0x87430979EEB424F2, 0x4D75F319566660DA, 0x30CD05437A146239, 0xA2641600BDE8C04, 0x712AA3BE},
{0xCF43C7FB897F2FE2, 0x3C7FB84C2F0E011E, 0xFB84C2F0E011ECF4, 0x4C2F0E011ECF43C7, 0x751C11ECF43C7FB8, 0x1D007C113B5D095, 0x4235B0D5E66773CE, 0x9E42B6C94350F39E, 0xB98F10656ABF493B, 0xA2738C79, 0xC023D9E87818892A, 0x3D9E878FF70985E1, 0xE878FF70985E1C02, 0x8FF70985E1C023D9, 0x52445E1C023D9E87, 0xC4A56A1DB3037852, 0xBE1F9B0F8C463146, 0xD7DB04211C8A255B, 0x87C4C4B67CF93C1C, 0x96C2BFBD},
{0xBB5E4448409D1B64, 0x9650668A321ACCD8, 0x48D39ADBC2F1339E, 0x8F7071B9DA7AD093, 0xDC2BFF88AE51552D, 0x67B12046E4504FA2, 0xDAC40568A6E7ACA6, 0x62ACCE83A2BE7FE7, 0xCEBB880D5DC0D19E, 0x25FA2A502, 0x12FE408DB093593F, 0xAAF044FB38FAC1A9, 0x2726CD500D0CEF1, 0x1605D37D0757467F, 0x1B66F6542117A77, 0x1350C0D1B1A7435E, 0x51F0069F69135871, 0x203791450029A4BC, 0x42B7E3FCB870BE19, 0x1CDC6F300},
{0x7B5CB802B56792C7, 0xBD1E27BB33DC664B, 0xC2399B484A347FD4, 0x5CB802B42E1D844C, 0x7699BB33DC664B7B, 0xA62220120D0CB91A, 0x24AAF6ED9C3527F0, 0x1FA962A3FE0A08F3, 0x219A48CC422DF1B1, 0x118AF1785, 0x2085638DAFEB8A83, 0xFD68A923B68BC5DE, 0x9743A21DF7A9C724, 0x85638DB029756DC4, 0x9A323B68BC5DE20, 0xDC5A0F3CC5799C18, 0x3CDBDDF993C3E933, 0x399816785890182E, 0x3DDF5FEAA7F4990C, 0xAC3F3421},
{0x63BDA9468BD342F5, 0x7403E8DA50E41EF7, 0x7B32C72BE3C39E62, 0xA4AEF030E69A6DAF, 0xC8E9EC938255BB45, 0x5AE36274AC3BB919, 0xAF73A8FEA01C6E98, 0x6C9E0C391AEA075A, 0xDE3F1DFEA825A09A, 0x495C0A99, 0xCDBBE48241B79B59, 0x29FF396B0854C507, 0xC91466B43E7DC219, 0xA46772E1FAE15C03, 0xC113B29586A5D8CF, 0x44FE6A6E5B9FB7B0, 0x11825F97D892585E, 0xC1F3209A0E0006B4, 0x313425C4139E19C4, 0x14DB5D37A},
{0x3011EB8A0C610EAE, 0x8632968FCBEC6D1D, 0xEF749BB7DE6283EB, 0x1038A58CDB855B10, 0x5574052BEBB46182, 0xB3E1CF3C83597C0F, 0xA718ADD06AD56610, 0x359FB5AA447520F6, 0xCDF6E662B8EB669C, 0x9CC50ACC, 0x4E213592827CF602, 0xB80C916F6BF2EBB6, 0xD05F9D238FE11743, 0x5FC7793D16D042BF, 0xBD58FD8E99F594EA, 0xC1100B4C07C4A897, 0x29F16A0996A54969, 0x3A7EB43A7FC5530D, 0xB3EF41DC7BE3CE6C, 0x4A3A4407},
{0x32CEC987C02E1E16, 0xB7E44C9BBD497EE5, 0x59C0313782E83DF1, 0x2C71AF09B871F5DE, 0xE44DFBF49F9CEA51, 0xC4BD0DF1CC341EB3, 0x7EC7C21EE53DE39D, 0x2B1B1BB9C6276C2C, 0xF86DE3A5ABE9539E, 0x2302FFE8B, 0x28DF22C8DCD7982F, 0x426541E94DCF04E7, 0x98CA1BA8F9B2855A, 0xF4067E6F7EA49E1D, 0xD03034D68F095472, 0x7D26821B325A3A85, 0x87DB2B11EC3322D6, 0x73BAAA33C117FB57, 0x92225964AC014B47, 0x12E0D7FE7},
{0xDF2479A490E3F3DA, 0xE07894F7FF684C36, 0x9A5E7229EF62380A, 0xE88DF8EE954C69A4, 0x800A8000EAE4D453, 0xAE77A73EF2BD6B7D, 0xDA18723BBC2CA8D7, 0xF186FA30727D2A31, 0x291452F619104C5B, 0x1E7F1399, 0x3732F21D651B1FEE, 0x8DDCCB2BDD071E43, 0x9641B49A54A8A116, 0xDA68148CA4D341DD, 0xC32B7A049A23B8F4, 0x24932D3124EB482F, 0x84AE00B5C46870B9, 0xCEAE14C3C3D55562, 0x97148EC2C4193A5, 0x1D94CB43},
{0x5DDBBCF90B937BD9, 0x3E84379AA3442E8, 0xCC25DC2808E0C528, 0xFB444A0D98465DEB, 0xD69F5A96BE71AC2C, 0x13938F1D6E581318, 0x37AE0B4F7DAC04ED, 0x863F2AD318BF5A7F, 0x397673E27BAC9DEA, 0x1216A9621, 0x904B65B8E15A658, 0xC7BB97BD7B0C45E2, 0x93CD91DECA863B07, 0x7E159E553BF8497, 0x5075FEF394A53914, 0xE7E384970BABE75A, 0x5968B82EF98ECFC6, 0x29B5FE78CEF214F8, 0xE3F63B7F9DF9725C, 0xFDF9B378},
{0x57CC8084740AF239, 0x5703E093ED1DEC26, 0x700B10597FE6838D, 0xBDADB8A8DE7E5988, 0x3EEB9E3F634109D8, 0xC632284A295D87A2, 0xFF7ED47380421F0, 0x46A42D85372D6D51, 0xCEB02C53FD6561AD, 0x68700397, 0x94083C312FDD1CCF, 0x8D8BBEBC2683FDD4, 0xDF6AA14583575AC1, 0xDF3FF19FF44AEEA3, 0xCEBEB4FB032ECD7D, 0x9CE783658636286, 0x7B3D4444C53B3D32, 0xB8749FA7F3A9070, 0xC415DCDB6A0AD61E, 0xB7869319},
{0x139CF42869D49482, 0xBC6F0C720A8973B, 0x28E407583814A9E0, 0xF00EFBF2ED7F95AF, 0x7D480A57AEF5BFD3, 0x7EC46EDF97D9EAC2, 0xB3F987339979273B, 0x699F07E12CA4729D, 0x7A1D6F1D94D877DD, 0x24F8BFBDA, 0x971EC29363AFF4EF, 0xA525D0504E28FD9, 0xB1499925B9A9134F, 0x3790DCE6BA9C9907, 0x9E2EB2BD7D2BDE58, 0xB1A37E98CE909692, 0x4C9EB9AB58C0D4A9, 0x77A16CF26A2492C6, 0xB2121E58A818AFB2, 0x5FF8FB81},
{0xD59C657588B26B4C, 0xB824E399449753E5, 0xB2EA59D067504894, 0x2E77C98265BE8415, 0x3A34AD15D89E7895, 0x6AA2E3EAB0F65905, 0x3A464491A81B6AD6, 0x64AFCC145F1EE37C, 0xEF30841D92867D4C, 0x1653C11AC, 0xC4A62DC72662944A, 0x4BC6EC7683E05B2E, 0xDE0AB70705491613, 0x7FC5FD6400FBAE3A, 0xBE093F12B7441F4E, 0x754D61F85BE9B748, 0xED144F4AD57B89A0, 0x4B6DFB51DECE2551, 0x67980426FCD240D0, 0x75699852},
{0xD3D4BB413D7061BE, 0x18AEC9D6854ECB25, 0x74912785EEF65EF3, 0x428B21B602840579, 0x7BEDFBC19961AB28, 0xE537045DFA2E6F0C, 0xAF709EC9946F55BB, 0xD4633E3CA2BBFE3D, 0xDDF84B965ACD8170, 0x1837A2775, 0xFB8249F345205225, 0xDC81B2C34B0B30FC, 0xF5B9D98AC4766CBA, 0x8B37B96AC565EDF5, 0xAB88EC455AB3E730, 0xF99410A2815AE199, 0x926C8A85493EB093, 0xC7082D622A51444B, 0xFE11910D6EC752C1, 0x22D0E6336},
{0xFBDC842A96D96B13, 0xEE3034ABA5D2EC9A, 0x5D4BFE83ECA3D306, 0x10CE1C3DB0210EC, 0x645EB45E9AC10E46, 0x99085D8D171BC2BE, 0x9F361AF1FC456B18, 0x8D9D38D8C416A25, 0xB071C0B7D59CE33C, 0xD89DA6CB, 0x770A7B6239055C1F, 0xE9767FC8D42B73D3, 0xFCC1954DC3AC1EE7, 0x1251746D17D4CA40, 0xD83FEEE6736971D, 0xB0210B1F8D0AB262, 0x3DE49D676CD13FB7, 0x1657FEBB10C212AF, 0x2F61A2D8A3F81312, 0x18E3342F8},
{0xD08AB92DAE048DB1, 0xAFDFB841D45B6CDB, 0x4E16B9F649DBDAD4, 0x8F7BD80A86CD6FE4, 0xE9D860EE31368282, 0xAB87FA97EF9B4B4E, 0x595B5FD6D5CD3C22, 0x8B2AF45E9CDA91B3, 0x2DFE5B32A817912D, 0x1FB079EE, 0x6B3EC443091B482D, 0x9248D66829014899, 0x638D81CC4AE199D, 0x5E8DE73EEB6DE96A, 0x55771848724D17F0, 0x734CB651B4339600, 0xFD2432CB79D99C1B, 0x373869CEA55DDEC4, 0x39D83CB6F4815AF5, 0xD31D84E9},
{0x8FC08908D008677E, 0xF50D53E90F7118D4, 0x38984342BC5C5F12, 0x9EF8ADEE9D890053, 0x2E9134B510F28488, 0x8951AC1CA56CA72C, 0x7CFED4FEED36EDEC, 0xCDF3038414AC384C, 0xA2C3889B433C8C6F, 0x27A01960F, 0xA3526DB518930119, 0xDC37B0E13644ED3F, 0x6E31E890F08A37BD, 0xA37A5E57024A8AA0, 0x40B194BE09CD892F, 0xF8D9FD2F6BFCA6BD, 0x20DFBAEF4B42549B, 0x45F0B1D7FBC11721, 0x5E7E3BB644063BE0, 0x171428956},
{0xB637BBC305F67791, 0x204FF0D2AEDF672E, 0xF92D3782494289DB, 0x24F7EB7320299A80, 0x977CC127123CD922, 0xB6C51C2947B68DB4, 0xBEFC8E5B0AE18F09, 0xFABDF4A65AAD3791, 0xAEBB5AA66A4EC660, 0x9F9CF17F, 0x110C3AF5E13E1951, 0xF40DC401CC686B06, 0x68EEA45A46B10505, 0x325395A25A0F0DE9, 0x1C92E56F56D28E24, 0xD0F8A55787894E1F, 0xEEEC7393357C5523, 0x5FB696B3518CC792, 0xD39D05F3A9382E5A, 0x26B74CDB1},
{0xBDF8A208F713F4A9, 0x18481280856177D9, 0x10BD738108662F2C, 0x1EF37C1AB5531600, 0x98D3C52040B3E9DB, 0x8E988D26C011FF69, 0x18AE98AA255688B, 0x8E60CDC1B136648B, 0x7E91BFE825833F56, 0x13DB93F4A, 0xC90DED2C7313B98, 0x82F6CE5855C8D3AC, 0xD22BF07E7380D124, 0xE912C49BBF549FD8, 0xBD34790D9C351C45, 0x4A1A372896AB66BF, 0x44E6AD3D3CB7D968, 0x473B9962DF10B605, 0x2DC4E87221525887, 0xD61465},
{0x3E77A9B726C4E35A, 0x72508865383E24E9, 0x703A850A1795B24B, 0xB744F39B78F82E6, 0xBCA3D4CB44C8DE88, 0x98BB9A1523EDC1A1, 0x1055B9EF0ED241A1, 0xDF619C4A7A3305B, 0xD3CAD19AFBE71CE8, 0x8A810A03, 0x78553A5AD2AFD1FC, 0x87C486E5D053F7C5, 0xD49A2C8D3988259, 0xD059B9BB567D1CB1, 0x5D10F35FBB64BF63, 0xB6A58DE0F78BF9DD, 0xCD0DEBAFEA4B0478, 0xDAF46A0964D3FD0A, 0x8E33C74FE2F70AFC, 0x21CAAD2F8},
{0x3BABE989C4B7C8C6, 0x2BF8F447EF3BDD7D, 0x20EAAD8C5457CF18, 0x8C176F27BA3E5B6D, 0x6994DF1010BAB10B, 0xC508E30E46C0CA1E, 0xA48AA3C16405257B, 0xFDA00D371BEC4681, 0x9D86B52EDF6EC9F8, 0x1C34BB8B6, 0xADB4F379816C780A, 0xC25F504173CEACF5, 0x1DA0375FEB0BBE8C, 0xB87264B37860585, 0xE0E1B8080C0215AB, 0xA4E2CD906374B7FC, 0x5326260B7A3021ED, 0x168C806A9FD020B4, 0xDD2E356F2066C037, 0x110BD582B}
};
// Setting up macro defines and including GF(p), GF(p^2), curve, isogeny and kex functions
#define fpcopy fpcopy610

File diff suppressed because it is too large Load Diff

View File

@ -1,80 +1,80 @@
/********************************************************************************************
* SIDH: an efficient supersingular isogeny cryptography library
*
* Abstract: modular arithmetic optimized for 64-bit ARMv8 platforms for P751
*********************************************************************************************/
#include "../P751_internal.h"
/* OQS note: this file is #include'd with the defs of these consts; removed to avoid re-defs
// Global constants
extern const uint64_t p751[NWORDS_FIELD];
extern const uint64_t p751x2[NWORDS_FIELD];
*/
__inline void fpadd751(const digit_t *a, const digit_t *b, digit_t *c) { // Modular addition, c = a+b mod p751.
// Inputs: a, b in [0, 2*p751-1]
// Output: c in [0, 2*p751-1]
oqs_kem_sike_fpadd751_asm(a, b, c);
}
__inline void fpsub751(const digit_t *a, const digit_t *b, digit_t *c) { // Modular subtraction, c = a-b mod p751.
// Inputs: a, b in [0, 2*p751-1]
// Output: c in [0, 2*p751-1]
oqs_kem_sike_fpsub751_asm(a, b, c);
}
__inline void fpneg751(digit_t *a) { // Modular negation, a = -a mod p751.
// Input/output: a in [0, 2*p751-1]
unsigned int i, borrow = 0;
for (i = 0; i < NWORDS_FIELD; i++) {
SUBC(borrow, ((digit_t *) p751x2)[i], a[i], borrow, a[i]);
}
}
void fpdiv2_751(const digit_t *a, digit_t *c) { // Modular division by two, c = a/2 mod p751.
// Input : a in [0, 2*p751-1]
// Output: c in [0, 2*p751-1]
unsigned int i, carry = 0;
digit_t mask;
mask = 0 - (digit_t)(a[0] & 1); // If a is odd compute a+p521
for (i = 0; i < NWORDS_FIELD; i++) {
ADDC(carry, a[i], ((digit_t *) p751)[i] & mask, carry, c[i]);
}
mp_shiftr1(c, NWORDS_FIELD);
}
void fpcorrection751(digit_t *a) { // Modular correction to reduce field element a in [0, 2*p751-1] to [0, p751-1].
unsigned int i, borrow = 0;
digit_t mask;
for (i = 0; i < NWORDS_FIELD; i++) {
SUBC(borrow, a[i], ((digit_t *) p751)[i], borrow, a[i]);
}
mask = 0 - (digit_t) borrow;
borrow = 0;
for (i = 0; i < NWORDS_FIELD; i++) {
ADDC(borrow, a[i], ((digit_t *) p751)[i] & mask, borrow, a[i]);
}
}
void mp_mul(const digit_t *a, const digit_t *b, digit_t *c, const unsigned int nwords) { // Multiprecision multiply, c = a*b, where lng(a) = lng(b) = nwords.
UNREFERENCED_PARAMETER(nwords);
oqs_kem_sike_mul751_asm(a, b, c);
}
void rdc_mont(digit_t *ma, digit_t *mc) { // Montgomery reduction exploiting special form of the prime.
// mc = ma*R^-1 mod p751x2, where R = 2^768.
// If ma < 2^768*p751, the output mc is in the range [0, 2*p751-1].
// ma is assumed to be in Montgomery representation.
oqs_kem_sike_rdc751_asm(ma, mc);
}
/********************************************************************************************
* SIDH: an efficient supersingular isogeny cryptography library
*
* Abstract: modular arithmetic optimized for 64-bit ARMv8 platforms for P751
*********************************************************************************************/
#include "../P751_internal.h"
/* OQS note: this file is #include'd with the defs of these consts; removed to avoid re-defs
// Global constants
extern const uint64_t p751[NWORDS_FIELD];
extern const uint64_t p751x2[NWORDS_FIELD];
*/
__inline void fpadd751(const digit_t *a, const digit_t *b, digit_t *c) { // Modular addition, c = a+b mod p751.
// Inputs: a, b in [0, 2*p751-1]
// Output: c in [0, 2*p751-1]
oqs_kem_sike_fpadd751_asm(a, b, c);
}
__inline void fpsub751(const digit_t *a, const digit_t *b, digit_t *c) { // Modular subtraction, c = a-b mod p751.
// Inputs: a, b in [0, 2*p751-1]
// Output: c in [0, 2*p751-1]
oqs_kem_sike_fpsub751_asm(a, b, c);
}
__inline void fpneg751(digit_t *a) { // Modular negation, a = -a mod p751.
// Input/output: a in [0, 2*p751-1]
unsigned int i, borrow = 0;
for (i = 0; i < NWORDS_FIELD; i++) {
SUBC(borrow, ((digit_t *) p751x2)[i], a[i], borrow, a[i]);
}
}
void fpdiv2_751(const digit_t *a, digit_t *c) { // Modular division by two, c = a/2 mod p751.
// Input : a in [0, 2*p751-1]
// Output: c in [0, 2*p751-1]
unsigned int i, carry = 0;
digit_t mask;
mask = 0 - (digit_t)(a[0] & 1); // If a is odd compute a+p521
for (i = 0; i < NWORDS_FIELD; i++) {
ADDC(carry, a[i], ((digit_t *) p751)[i] & mask, carry, c[i]);
}
mp_shiftr1(c, NWORDS_FIELD);
}
void fpcorrection751(digit_t *a) { // Modular correction to reduce field element a in [0, 2*p751-1] to [0, p751-1].
unsigned int i, borrow = 0;
digit_t mask;
for (i = 0; i < NWORDS_FIELD; i++) {
SUBC(borrow, a[i], ((digit_t *) p751)[i], borrow, a[i]);
}
mask = 0 - (digit_t) borrow;
borrow = 0;
for (i = 0; i < NWORDS_FIELD; i++) {
ADDC(borrow, a[i], ((digit_t *) p751)[i] & mask, borrow, a[i]);
}
}
void mp_mul(const digit_t *a, const digit_t *b, digit_t *c, const unsigned int nwords) { // Multiprecision multiply, c = a*b, where lng(a) = lng(b) = nwords.
UNREFERENCED_PARAMETER(nwords);
oqs_kem_sike_mul751_asm(a, b, c);
}
void rdc_mont(digit_t *ma, digit_t *mc) { // Montgomery reduction exploiting special form of the prime.
// mc = ma*R^-1 mod p751x2, where R = 2^768.
// If ma < 2^768*p751, the output mc is in the range [0, 2*p751-1].
// ma is assumed to be in Montgomery representation.
oqs_kem_sike_rdc751_asm(ma, mc);
}

View File

@ -1,150 +1,159 @@
/********************************************************************************************
* SIDH: an efficient supersingular isogeny cryptography library
*
* Abstract: supersingular isogeny parameters and generation of functions for P751
*********************************************************************************************/
#include <oqs/rand.h>
#include "../oqs_namespace_sike.h"
#include "P751_api.h"
#include "P751_internal.h"
// defines moved from P751_api.h
#define CRYPTO_SECRETKEYBYTES 644 // MSG_BYTES + SECRETKEY_B_BYTES + CRYPTO_PUBLICKEYBYTES bytes
#define CRYPTO_PUBLICKEYBYTES 564
#define CRYPTO_BYTES 32
#define CRYPTO_CIPHERTEXTBYTES 596 // CRYPTO_PUBLICKEYBYTES + MSG_BYTES bytes
#define SIDH_SECRETKEYBYTES_A 47
#define SIDH_SECRETKEYBYTES_B 48
#define SIDH_PUBLICKEYBYTES 564
#define SIDH_BYTES 188
// Encoding of field elements, elements over Z_order, elements over GF(p^2) and elliptic curve points:
// --------------------------------------------------------------------------------------------------
// Elements over GF(p) and Z_order are encoded with the least significant octet (and digit) located at the leftmost position (i.e., little endian format).
// Elements (a+b*i) over GF(p^2), where a and b are defined over GF(p), are encoded as {a, b}, with a in the least significant position.
// Elliptic curve points P = (x,y) are encoded as {x, y}, with x in the least significant position.
// Internally, the number of digits used to represent all these elements is obtained by approximating the number of bits to the immediately greater multiple of 32.
// For example, a 751-bit field element is represented with Ceil(751 / 64) = 12 64-bit digits or Ceil(751 / 32) = 24 32-bit digits.
//
// Curve isogeny system "SIDHp751". Base curve: Montgomery curve By^2 = Cx^3 + Ax^2 + Cx defined over GF(p751^2), where A=6, B=1, C=1 and p751 = 2^372*3^239-1
//
const uint64_t p751[NWORDS64_FIELD] = {0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xEEAFFFFFFFFFFFFF,
0xE3EC968549F878A8, 0xDA959B1A13F7CC76, 0x084E9867D6EBE876, 0x8562B5045CB25748, 0x0E12909F97BADC66, 0x00006FE5D541F71C};
const uint64_t p751p1[NWORDS64_FIELD] = {0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xEEB0000000000000,
0xE3EC968549F878A8, 0xDA959B1A13F7CC76, 0x084E9867D6EBE876, 0x8562B5045CB25748, 0x0E12909F97BADC66, 0x00006FE5D541F71C};
const uint64_t p751x2[NWORDS64_FIELD] = {0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xDD5FFFFFFFFFFFFF,
0xC7D92D0A93F0F151, 0xB52B363427EF98ED, 0x109D30CFADD7D0ED, 0x0AC56A08B964AE90, 0x1C25213F2F75B8CD, 0x0000DFCBAA83EE38};
// Order of Alice's subgroup
static const uint64_t Alice_order[NWORDS64_ORDER] = {0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0010000000000000};
// Order of Bob's subgroup
static const uint64_t Bob_order[NWORDS64_ORDER] = {0xC968549F878A8EEB, 0x59B1A13F7CC76E3E, 0xE9867D6EBE876DA9, 0x2B5045CB25748084, 0x2909F97BADC66856, 0x06FE5D541F71C0E1};
// Alice's generator values {XPA0 + XPA1*i, XQA0 + xQA1*i, XRA0 + XRA1*i} in GF(p751^2), expressed in Montgomery representation
static const uint64_t A_gen[6 * NWORDS64_FIELD] = {0x884F46B74000BAA8, 0xBA52630F939DEC20, 0xC16FB97BA714A04D, 0x082536745B1AB3DB, 0x1117157F446F9E82, 0xD2F27D621A018490,
0x6B24AB523D544BCD, 0x9307D6AA2EA85C94, 0xE1A096729528F20F, 0x896446F868F3255C, 0x2401D996B1BFF8A5, 0x00000EF8786A5C0A, // XPA0
0xAEB78B3B96F59394, 0xAB26681E29C90B74, 0xE520AC30FDC4ACF1, 0x870AAAE3A4B8111B, 0xF875BDB738D64EFF, 0x50109A7ECD7ED6BC,
0x4CC64848FF0C56FB, 0xE617CB6C519102C9, 0x9C74B3835921E609, 0xC91DDAE4A35A7146, 0x7FC82A155C1B9129, 0x0000214FA6B980B3, // XPA1
0x0F93CC38680A8CA9, 0x762E733822E7FED7, 0xE549F005AC0ADB67, 0x94A71FDD2C43A4ED, 0xD48645C2B04721C5, 0x432DA1FE4D4CA4DC,
0xBC99655FAA7A80E8, 0xB2C6D502BCFD4823, 0xEE92F40CA2EC8BDB, 0x7B074132EFB6D16C, 0x3340B46FA38A7633, 0x0000215749657F6C, // XQA0
0xECFF375BF3079F4C, 0xFBFE74B043E80EF3, 0x17376CBE3C5C7AD1, 0xC06327A7E29CDBF2, 0x2111649C438BF3D4, 0xC1F9298261BA2E97,
0x1F9FECE869CFD1C2, 0x01A39B4FC9346D62, 0x147CD1D3E82A3C9F, 0xDE84E9D249E533EE, 0x1C48A5ADFB7C578D, 0x000061ACA0B82E1D, // XQA1
0x1600C525D41059F1, 0xA596899A0A1D83F7, 0x6BFDEED6D2B23F35, 0x5C7E707270C23910, 0x276CA1A4E8369411, 0xB193651A602925A0,
0x243D239F1CA1F04A, 0x543DC6DA457860AD, 0xCDA590F325181DE9, 0xD3AB7ACFDA80B395, 0x6C97468580FDDF7B, 0x0000352A3E5C4C77, // XRA0
0x9B794F9FD1CC3EE8, 0xDB32E40A9B2FD23E, 0x26192A2542E42B67, 0xA18E94FCA045BCE7, 0x96DC1BC38E7CDA2D, 0x9A1D91B752487DE2,
0xCC63763987436DA3, 0x1316717AACCC551D, 0xC4C368A4632AFE72, 0x4B6EA85C9CCD5710, 0x7A12CAD582C7BC9A, 0x00001C7E240149BF}; // XRA1
// Bob's generator values {XPB0, XQB0, XRB0 + XRB1*i} in GF(p751^2), expressed in Montgomery representation
static const uint64_t B_gen[6 * NWORDS64_FIELD] = {0x85691AAF4015F88C, 0x7478C5B8C36E9631, 0x7EF2A185DE4DD6E2, 0x943BBEE46BEB9DC7, 0x1A3EC62798792D22, 0x791BC4B084B31D69,
0x03DBE6522CEA17C4, 0x04749AA65D665D83, 0x3D52B5C45EF450F3, 0x0B4219848E36947D, 0xA4CF7070466BDE27, 0x0000334B1FA6D193, // XPB0
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, // XPB1
0x8E7CB3FA53211340, 0xD67CE54F7A05EEE0, 0xFDDC2C8BCE46FC38, 0x08587FAE3110DF1E, 0xD6B8246FA22B058B, 0x4DAC3ACC905A5DBD,
0x51D0BF2FADCED3E8, 0xE5A2406DF6484425, 0x907F177584F671B8, 0x4738A2FFCCED051C, 0x2B0067B4177E4853, 0x00002806AC948D3D, // XQB0
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, // XQB1
0xB56457016D1D6D1C, 0x03DECCB38F39C491, 0xDFB910AC8A559452, 0xA9D0F17D1FF24883, 0x8562BBAF515C248C, 0x249B2A6DDB1CB67D,
0x3131AF96FB46835C, 0xE10258398480C3E1, 0xEAB5E2B872D4FAB1, 0xB71E63875FAEB1DF, 0xF8384D4F13757CF6, 0x0000361EC9B09912, // XRB0
0x58C967899ED16EF4, 0x81998376DC622A4B, 0x3D1C1DCFE0B12681, 0x9347DEBB953E1730, 0x9ABB344D3A82C2D7, 0xE4881BD2820552B2,
0x0037247923D90266, 0x2E3156EDB157E5A5, 0xF86A46A7506823F7, 0x8FE5523A7B7F1CFC, 0xFA3CFFA38372F67B, 0x0000692DCE85FFBD}; // XRB1
// Montgomery constant Montgomery_R2 = (2^768)^2 mod p751
static const uint64_t Montgomery_R2[NWORDS64_FIELD] = {0x233046449DAD4058, 0xDB010161A696452A, 0x5E36941472E3FD8E, 0xF40BFE2082A2E706, 0x4932CCA8904F8751, 0x1F735F1F1EE7FC81,
0xA24F4D80C1048E18, 0xB56C383CCDB607C5, 0x441DD47B735F9C90, 0x5673ED2C6A6AC82A, 0x06C905261132294B, 0x000041AD830F1F35};
// Value one in Montgomery representation
static const uint64_t Montgomery_one[NWORDS64_FIELD] = {0x00000000000249ad, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x8310000000000000,
0x5527b1e4375c6c66, 0x697797bf3f4f24d0, 0xc89db7b2ac5c4e2e, 0x4ca4b439d2076956, 0x10f7926c7512c7e9, 0x00002d5b24bce5e2};
// Fixed parameters for isogeny tree computation
static const unsigned int strat_Alice[MAX_Alice - 1] = {
80, 48, 27, 15, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 7, 4, 2, 1, 1, 2, 1,
1, 3, 2, 1, 1, 1, 1, 12, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 5, 3, 2, 1, 1,
1, 1, 2, 1, 1, 1, 21, 12, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 5, 3, 2, 1,
1, 1, 1, 2, 1, 1, 1, 9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1,
33, 20, 12, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 5, 3, 2, 1, 1, 1, 1, 2, 1,
1, 1, 8, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 2, 1, 1, 16, 8, 4, 2, 1, 1,
1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1};
static const unsigned int strat_Bob[MAX_Bob - 1] = {
112, 63, 32, 16, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1,
1, 4, 2, 1, 1, 2, 1, 1, 16, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2,
1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 31, 16, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2,
1, 1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 15, 8, 4, 2, 1, 1, 2, 1, 1, 4,
2, 1, 1, 2, 1, 1, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 49, 31, 16, 8, 4, 2,
1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1,
15, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1,
1, 1, 1, 21, 12, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 5, 3, 2, 1, 1, 1, 1,
2, 1, 1, 1, 9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1};
// Setting up macro defines and including GF(p), GF(p^2), curve, isogeny and kex functions
#define fpcopy fpcopy751
#define fpzero fpzero751
#define fpadd fpadd751
#define fpsub fpsub751
#define fpneg fpneg751
#define fpdiv2 fpdiv2_751
#define fpcorrection fpcorrection751
#define fpmul_mont fpmul751_mont
#define fpsqr_mont fpsqr751_mont
#define fpinv_mont fpinv751_mont
#define fpinv_chain_mont fpinv751_chain_mont
#define fpinv_mont_bingcd fpinv751_mont_bingcd
#define fp2copy fp2copy751
#define fp2zero fp2zero751
#define fp2add fp2add751
#define fp2sub fp2sub751
#define fp2neg fp2neg751
#define fp2div2 fp2div2_751
#define fp2correction fp2correction751
#define fp2mul_mont fp2mul751_mont
#define fp2sqr_mont fp2sqr751_mont
#define fp2inv_mont fp2inv751_mont
#define fp2inv_mont_bingcd fp2inv751_mont_bingcd
#define fpequal_non_constant_time fpequal751_non_constant_time
#define mp_add_asm oqs_kem_sike_mp_add751_asm
#define mp_subaddx2_asm oqs_kem_sike_mp_subadd751x2_asm
#define mp_dblsubx2_asm oqs_kem_sike_mp_dblsub751x2_asm
#define crypto_kem_keypair OQS_KEM_sike_p751_keypair
#define crypto_kem_enc OQS_KEM_sike_p751_encaps
#define crypto_kem_dec OQS_KEM_sike_p751_decaps
#define random_mod_order_A oqs_kem_sidh_p751_random_mod_order_A
#define random_mod_order_B oqs_kem_sidh_p751_random_mod_order_B
#define EphemeralKeyGeneration_A oqs_kem_sidh_p751_EphemeralKeyGeneration_A
#define EphemeralKeyGeneration_B oqs_kem_sidh_p751_EphemeralKeyGeneration_B
#define EphemeralSecretAgreement_A oqs_kem_sidh_p751_EphemeralSecretAgreement_A
#define EphemeralSecretAgreement_B oqs_kem_sidh_p751_EphemeralSecretAgreement_B
#ifdef USE_SIKEP751_ASM
#define USE_SIKE_ASM
#endif
#if defined(X86_64)
#include "AMD64/fp_x64.c"
#elif defined(ARM64)
#include "ARM64/fp_arm64.c"
#else
#include "generic/fp_generic.c"
#endif
#include "../fpx.c"
#include "../ec_isogeny.c"
#include "../sidh.c"
#include "../sike.c"
/********************************************************************************************
* SIDH: an efficient supersingular isogeny cryptography library
*
* Abstract: supersingular isogeny parameters and generation of functions for P751
*********************************************************************************************/
#include <oqs/rand.h>
#include "../oqs_namespace_sike.h"
#include "P751_api.h"
#include "P751_internal.h"
// defines moved from P751_api.h
#define CRYPTO_SECRETKEYBYTES 644 // MSG_BYTES + SECRETKEY_B_BYTES + CRYPTO_PUBLICKEYBYTES bytes
#define CRYPTO_PUBLICKEYBYTES 564
#define CRYPTO_BYTES 32
#define CRYPTO_CIPHERTEXTBYTES 596 // CRYPTO_PUBLICKEYBYTES + MSG_BYTES bytes
#define SIDH_SECRETKEYBYTES_A 47
#define SIDH_SECRETKEYBYTES_B 48
#define SIDH_PUBLICKEYBYTES 564
#define SIDH_BYTES 188
// Encoding of field elements, elements over Z_order, elements over GF(p^2) and elliptic curve points:
// --------------------------------------------------------------------------------------------------
// Elements over GF(p) and Z_order are encoded with the least significant octet (and digit) located at the leftmost position (i.e., little endian format).
// Elements (a+b*i) over GF(p^2), where a and b are defined over GF(p), are encoded as {a, b}, with a in the least significant position.
// Elliptic curve points P = (x,y) are encoded as {x, y}, with x in the least significant position.
// Internally, the number of digits used to represent all these elements is obtained by approximating the number of bits to the immediately greater multiple of 32.
// For example, a 751-bit field element is represented with Ceil(751 / 64) = 12 64-bit digits or Ceil(751 / 32) = 24 32-bit digits.
//
// Curve isogeny system "SIDHp751". Base curve: Montgomery curve By^2 = Cx^3 + Ax^2 + Cx defined over GF(p751^2), where A=6, B=1, C=1 and p751 = 2^372*3^239-1
//
const uint64_t p751[NWORDS64_FIELD] = {0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xEEAFFFFFFFFFFFFF,
0xE3EC968549F878A8, 0xDA959B1A13F7CC76, 0x084E9867D6EBE876, 0x8562B5045CB25748, 0x0E12909F97BADC66, 0x00006FE5D541F71C
};
const uint64_t p751p1[NWORDS64_FIELD] = {0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xEEB0000000000000,
0xE3EC968549F878A8, 0xDA959B1A13F7CC76, 0x084E9867D6EBE876, 0x8562B5045CB25748, 0x0E12909F97BADC66, 0x00006FE5D541F71C
};
const uint64_t p751x2[NWORDS64_FIELD] = {0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xDD5FFFFFFFFFFFFF,
0xC7D92D0A93F0F151, 0xB52B363427EF98ED, 0x109D30CFADD7D0ED, 0x0AC56A08B964AE90, 0x1C25213F2F75B8CD, 0x0000DFCBAA83EE38
};
// Order of Alice's subgroup
static const uint64_t Alice_order[NWORDS64_ORDER] = {0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0010000000000000};
// Order of Bob's subgroup
static const uint64_t Bob_order[NWORDS64_ORDER] = {0xC968549F878A8EEB, 0x59B1A13F7CC76E3E, 0xE9867D6EBE876DA9, 0x2B5045CB25748084, 0x2909F97BADC66856, 0x06FE5D541F71C0E1};
// Alice's generator values {XPA0 + XPA1*i, XQA0 + xQA1*i, XRA0 + XRA1*i} in GF(p751^2), expressed in Montgomery representation
static const uint64_t A_gen[6 * NWORDS64_FIELD] = {0x884F46B74000BAA8, 0xBA52630F939DEC20, 0xC16FB97BA714A04D, 0x082536745B1AB3DB, 0x1117157F446F9E82, 0xD2F27D621A018490,
0x6B24AB523D544BCD, 0x9307D6AA2EA85C94, 0xE1A096729528F20F, 0x896446F868F3255C, 0x2401D996B1BFF8A5, 0x00000EF8786A5C0A, // XPA0
0xAEB78B3B96F59394, 0xAB26681E29C90B74, 0xE520AC30FDC4ACF1, 0x870AAAE3A4B8111B, 0xF875BDB738D64EFF, 0x50109A7ECD7ED6BC,
0x4CC64848FF0C56FB, 0xE617CB6C519102C9, 0x9C74B3835921E609, 0xC91DDAE4A35A7146, 0x7FC82A155C1B9129, 0x0000214FA6B980B3, // XPA1
0x0F93CC38680A8CA9, 0x762E733822E7FED7, 0xE549F005AC0ADB67, 0x94A71FDD2C43A4ED, 0xD48645C2B04721C5, 0x432DA1FE4D4CA4DC,
0xBC99655FAA7A80E8, 0xB2C6D502BCFD4823, 0xEE92F40CA2EC8BDB, 0x7B074132EFB6D16C, 0x3340B46FA38A7633, 0x0000215749657F6C, // XQA0
0xECFF375BF3079F4C, 0xFBFE74B043E80EF3, 0x17376CBE3C5C7AD1, 0xC06327A7E29CDBF2, 0x2111649C438BF3D4, 0xC1F9298261BA2E97,
0x1F9FECE869CFD1C2, 0x01A39B4FC9346D62, 0x147CD1D3E82A3C9F, 0xDE84E9D249E533EE, 0x1C48A5ADFB7C578D, 0x000061ACA0B82E1D, // XQA1
0x1600C525D41059F1, 0xA596899A0A1D83F7, 0x6BFDEED6D2B23F35, 0x5C7E707270C23910, 0x276CA1A4E8369411, 0xB193651A602925A0,
0x243D239F1CA1F04A, 0x543DC6DA457860AD, 0xCDA590F325181DE9, 0xD3AB7ACFDA80B395, 0x6C97468580FDDF7B, 0x0000352A3E5C4C77, // XRA0
0x9B794F9FD1CC3EE8, 0xDB32E40A9B2FD23E, 0x26192A2542E42B67, 0xA18E94FCA045BCE7, 0x96DC1BC38E7CDA2D, 0x9A1D91B752487DE2,
0xCC63763987436DA3, 0x1316717AACCC551D, 0xC4C368A4632AFE72, 0x4B6EA85C9CCD5710, 0x7A12CAD582C7BC9A, 0x00001C7E240149BF
}; // XRA1
// Bob's generator values {XPB0, XQB0, XRB0 + XRB1*i} in GF(p751^2), expressed in Montgomery representation
static const uint64_t B_gen[6 * NWORDS64_FIELD] = {0x85691AAF4015F88C, 0x7478C5B8C36E9631, 0x7EF2A185DE4DD6E2, 0x943BBEE46BEB9DC7, 0x1A3EC62798792D22, 0x791BC4B084B31D69,
0x03DBE6522CEA17C4, 0x04749AA65D665D83, 0x3D52B5C45EF450F3, 0x0B4219848E36947D, 0xA4CF7070466BDE27, 0x0000334B1FA6D193, // XPB0
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, // XPB1
0x8E7CB3FA53211340, 0xD67CE54F7A05EEE0, 0xFDDC2C8BCE46FC38, 0x08587FAE3110DF1E, 0xD6B8246FA22B058B, 0x4DAC3ACC905A5DBD,
0x51D0BF2FADCED3E8, 0xE5A2406DF6484425, 0x907F177584F671B8, 0x4738A2FFCCED051C, 0x2B0067B4177E4853, 0x00002806AC948D3D, // XQB0
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, // XQB1
0xB56457016D1D6D1C, 0x03DECCB38F39C491, 0xDFB910AC8A559452, 0xA9D0F17D1FF24883, 0x8562BBAF515C248C, 0x249B2A6DDB1CB67D,
0x3131AF96FB46835C, 0xE10258398480C3E1, 0xEAB5E2B872D4FAB1, 0xB71E63875FAEB1DF, 0xF8384D4F13757CF6, 0x0000361EC9B09912, // XRB0
0x58C967899ED16EF4, 0x81998376DC622A4B, 0x3D1C1DCFE0B12681, 0x9347DEBB953E1730, 0x9ABB344D3A82C2D7, 0xE4881BD2820552B2,
0x0037247923D90266, 0x2E3156EDB157E5A5, 0xF86A46A7506823F7, 0x8FE5523A7B7F1CFC, 0xFA3CFFA38372F67B, 0x0000692DCE85FFBD
}; // XRB1
// Montgomery constant Montgomery_R2 = (2^768)^2 mod p751
static const uint64_t Montgomery_R2[NWORDS64_FIELD] = {0x233046449DAD4058, 0xDB010161A696452A, 0x5E36941472E3FD8E, 0xF40BFE2082A2E706, 0x4932CCA8904F8751, 0x1F735F1F1EE7FC81,
0xA24F4D80C1048E18, 0xB56C383CCDB607C5, 0x441DD47B735F9C90, 0x5673ED2C6A6AC82A, 0x06C905261132294B, 0x000041AD830F1F35
};
// Value one in Montgomery representation
static const uint64_t Montgomery_one[NWORDS64_FIELD] = {0x00000000000249ad, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x8310000000000000,
0x5527b1e4375c6c66, 0x697797bf3f4f24d0, 0xc89db7b2ac5c4e2e, 0x4ca4b439d2076956, 0x10f7926c7512c7e9, 0x00002d5b24bce5e2
};
// Fixed parameters for isogeny tree computation
static const unsigned int strat_Alice[MAX_Alice - 1] = {
80, 48, 27, 15, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 7, 4, 2, 1, 1, 2, 1,
1, 3, 2, 1, 1, 1, 1, 12, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 5, 3, 2, 1, 1,
1, 1, 2, 1, 1, 1, 21, 12, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 5, 3, 2, 1,
1, 1, 1, 2, 1, 1, 1, 9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1,
33, 20, 12, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 5, 3, 2, 1, 1, 1, 1, 2, 1,
1, 1, 8, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 2, 1, 1, 16, 8, 4, 2, 1, 1,
1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1
};
static const unsigned int strat_Bob[MAX_Bob - 1] = {
112, 63, 32, 16, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1,
1, 4, 2, 1, 1, 2, 1, 1, 16, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2,
1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 31, 16, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2,
1, 1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 15, 8, 4, 2, 1, 1, 2, 1, 1, 4,
2, 1, 1, 2, 1, 1, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 49, 31, 16, 8, 4, 2,
1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1,
15, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1,
1, 1, 1, 21, 12, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 5, 3, 2, 1, 1, 1, 1,
2, 1, 1, 1, 9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1
};
// Setting up macro defines and including GF(p), GF(p^2), curve, isogeny and kex functions
#define fpcopy fpcopy751
#define fpzero fpzero751
#define fpadd fpadd751
#define fpsub fpsub751
#define fpneg fpneg751
#define fpdiv2 fpdiv2_751
#define fpcorrection fpcorrection751
#define fpmul_mont fpmul751_mont
#define fpsqr_mont fpsqr751_mont
#define fpinv_mont fpinv751_mont
#define fpinv_chain_mont fpinv751_chain_mont
#define fpinv_mont_bingcd fpinv751_mont_bingcd
#define fp2copy fp2copy751
#define fp2zero fp2zero751
#define fp2add fp2add751
#define fp2sub fp2sub751
#define fp2neg fp2neg751
#define fp2div2 fp2div2_751
#define fp2correction fp2correction751
#define fp2mul_mont fp2mul751_mont
#define fp2sqr_mont fp2sqr751_mont
#define fp2inv_mont fp2inv751_mont
#define fp2inv_mont_bingcd fp2inv751_mont_bingcd
#define fpequal_non_constant_time fpequal751_non_constant_time
#define mp_add_asm oqs_kem_sike_mp_add751_asm
#define mp_subaddx2_asm oqs_kem_sike_mp_subadd751x2_asm
#define mp_dblsubx2_asm oqs_kem_sike_mp_dblsub751x2_asm
#define crypto_kem_keypair OQS_KEM_sike_p751_keypair
#define crypto_kem_enc OQS_KEM_sike_p751_encaps
#define crypto_kem_dec OQS_KEM_sike_p751_decaps
#define random_mod_order_A oqs_kem_sidh_p751_random_mod_order_A
#define random_mod_order_B oqs_kem_sidh_p751_random_mod_order_B
#define EphemeralKeyGeneration_A oqs_kem_sidh_p751_EphemeralKeyGeneration_A
#define EphemeralKeyGeneration_B oqs_kem_sidh_p751_EphemeralKeyGeneration_B
#define EphemeralSecretAgreement_A oqs_kem_sidh_p751_EphemeralSecretAgreement_A
#define EphemeralSecretAgreement_B oqs_kem_sidh_p751_EphemeralSecretAgreement_B
#ifdef USE_SIKEP751_ASM
#define USE_SIKE_ASM
#endif
#if defined(X86_64)
#include "AMD64/fp_x64.c"
#elif defined(ARM64)
#include "ARM64/fp_arm64.c"
#else
#include "generic/fp_generic.c"
#endif
#include "../fpx.c"
#include "../ec_isogeny.c"
#include "../sidh.c"
#include "../sike.c"

View File

@ -33,11 +33,14 @@
//
static const uint64_t p751[NWORDS64_FIELD] = {0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xEEAFFFFFFFFFFFFF,
0xE3EC968549F878A8, 0xDA959B1A13F7CC76, 0x084E9867D6EBE876, 0x8562B5045CB25748, 0x0E12909F97BADC66, 0x00006FE5D541F71C};
0xE3EC968549F878A8, 0xDA959B1A13F7CC76, 0x084E9867D6EBE876, 0x8562B5045CB25748, 0x0E12909F97BADC66, 0x00006FE5D541F71C
};
static const uint64_t p751p1[NWORDS64_FIELD] = {0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xEEB0000000000000,
0xE3EC968549F878A8, 0xDA959B1A13F7CC76, 0x084E9867D6EBE876, 0x8562B5045CB25748, 0x0E12909F97BADC66, 0x00006FE5D541F71C};
0xE3EC968549F878A8, 0xDA959B1A13F7CC76, 0x084E9867D6EBE876, 0x8562B5045CB25748, 0x0E12909F97BADC66, 0x00006FE5D541F71C
};
static const uint64_t p751x2[NWORDS64_FIELD] = {0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xDD5FFFFFFFFFFFFF,
0xC7D92D0A93F0F151, 0xB52B363427EF98ED, 0x109D30CFADD7D0ED, 0x0AC56A08B964AE90, 0x1C25213F2F75B8CD, 0x0000DFCBAA83EE38};
0xC7D92D0A93F0F151, 0xB52B363427EF98ED, 0x109D30CFADD7D0ED, 0x0AC56A08B964AE90, 0x1C25213F2F75B8CD, 0x0000DFCBAA83EE38
};
// Order of Alice's subgroup
static const uint64_t Alice_order[NWORDS64_ORDER] = {0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0010000000000000};
// Order of Bob's subgroup
@ -55,7 +58,8 @@ static const uint64_t A_gen[6 * NWORDS64_FIELD] = {0x2584350E0C33C304, 0x51E9C29
0xC04B8957D3A4748F, 0xF3FB80F19063629F, 0x595434555D4EBE94, 0x8E1FEF11BFD1E0DA, 0xE31E3377248C0BB4, 0x9A05DEFF75EA51BA,
0x398686FBB343398A, 0x20331307B470DA54, 0x964FA62AD10005C5, 0x9EA5CC4D64E5D9EE, 0xC84675CF9B96060F, 0x1DECCB78CFAC, // XRA0
0x6B20FF684759DDC2, 0xD50EB91730DEAFBF, 0xAA5CA048E2DAF488, 0xE29708E28654FC18, 0x542928AD1F445359, 0xA311B83D79E73FF6,
0x850B7F5926826B22, 0x2D46731863BDB99D, 0x467A80CD8320B69D, 0xC046B12F05BFD513, 0x35D9B2FF794BDB40, 0x633276495B85}; // XRA1
0x850B7F5926826B22, 0x2D46731863BDB99D, 0x467A80CD8320B69D, 0xC046B12F05BFD513, 0x35D9B2FF794BDB40, 0x633276495B85
}; // XRA1
/* Basis for Bob on A = 6, expressed in Montgomery representation */
static const uint64_t B_gen[6 * NWORDS64_FIELD] = {0x110F4508C6634CCB, 0x31910BC05E296F4C, 0xED17AB0D6C029EA6, 0x9C863AB6172B9974, 0x5C15236CDB216F99, 0xDC025064818EC7D7,
@ -68,13 +72,15 @@ static const uint64_t B_gen[6 * NWORDS64_FIELD] = {0x110F4508C6634CCB, 0x31910BC
0x3C683C8422E2DF33, 0xC9F7CDAC81470884, 0xC22A5F9AD5EAFA48, 0x89EA4B11AAD2D65C, 0xB7D78449A6CC0012, 0x568D11C4AFFA, // XQB1
0x31BB0964DFBDC34F, 0xFDC65CF4959AB106, 0xA3071E4B8B04D8FF, 0x9B68CFCE270DE486, 0x2339E590896E0095, 0xFC753508AD83E33E,
0x73A274E4A6908387, 0x88D1B207BBE8E2DC, 0xA6D0583233DC71F, 0xCF7F2ECC609DE5BE, 0xB8AF0669FBD1CF01, 0x1F3EF25DD512, // XRB0
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; // XRB1
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
}; // XRB1
/* The x-coordinate of lB^(eB-1)*QB, expressed in Montgomery representation */
static const uint64_t XQB3[2 * NWORDS64_FIELD] = {0x96DCB5BD39AA8288, 0x81E7BA9AA19C1C53, 0x7021384077E4FEB6, 0xA1490C7A753E8E74, 0xA31871E13D80831C, 0x7E653AD5931BC82E,
0x8A0C230821766ECA, 0x1CE14E07EB29B669, 0xF985F42F404E45EF, 0x44AF699D9546F9B, 0x8A8C976EE869BE6B, 0xEC5AA84C390,
0xF16AEFC3FA025CCB, 0x205E4E1559261A6E, 0xFA6EEE97610CA4AA, 0x4B29DB4DF10E7D9, 0x83BC8A148E0FBB2, 0x1065373142BD8B81,
0xD7C4A7221ED3E403, 0x1071E13BCEB89A2A, 0x54A18AEA86CD9D51, 0x39BF04224B598D62, 0xD4B89FF2AA465908, 0x5A0F792EB1A3};
0xD7C4A7221ED3E403, 0x1071E13BCEB89A2A, 0x54A18AEA86CD9D51, 0x39BF04224B598D62, 0xD4B89FF2AA465908, 0x5A0F792EB1A3
};
static const uint64_t A_basis_zero[8 * NWORDS64_FIELD] = {0x2584350E0C38565F, 0x51E9C29E234DC61E, 0xC6E65A7BF90ACC05, 0xB1333E2E19B3A930, 0xA4F7CA2F7F66909F, 0xF78E9E6F6704BF9E,
0xA8972A8BE4E1FD91, 0x694D0F3DFDE63EAC, 0x48A2455F29C6089, 0x4F74628F6069C173, 0x1EDF6B38ED1A5433, 0x74AA0969CE,
@ -91,7 +97,8 @@ static const uint64_t A_basis_zero[8 * NWORDS64_FIELD] = {0x2584350E0C38565F, 0x
0xD976D6B7056D9BE, 0x269169101B22C490, 0x485B7EFC9E5BBC09, 0xD0B55BEABD8EF10, 0x985F36CD657501DD, 0x19FD14B27B195F17,
0xF0F7E577A00E0E42, 0x1A179D4A080F58D2, 0x97603A54D8CFB3E5, 0x96E69A6743A68CE1, 0xF04C8D027EB4B382, 0xA8E741B2F5C,
0xBBF34629BA51923B, 0x94250E3ECE841C7C, 0x56CD785FA63E19F9, 0x126F4144FC6B39F4, 0x4BB54DEE559E01E3, 0x3195B2E094E0D92,
0x1F40204597E534A, 0x7F9B8D473586B966, 0x38281C1E6F54E744, 0x215C5889B91D5D63, 0x9CEA26343AD2B060, 0x22374E0C0255};
0x1F40204597E534A, 0x7F9B8D473586B966, 0x38281C1E6F54E744, 0x215C5889B91D5D63, 0x9CEA26343AD2B060, 0x22374E0C0255
};
/* Basis for Bob on A = 0, expressed in Montgomery representation */
static const uint64_t B_basis_zero[8 * NWORDS64_FIELD] = {0xF1A8C9ED7B96C4AB, 0x299429DA5178486E, 0xEF4926F20CD5C2F4, 0x683B2E2858B4716A, 0xDDA2FBCC3CAC3EEB, 0xEC055F9F3A600460,
@ -105,7 +112,8 @@ static const uint64_t B_basis_zero[8 * NWORDS64_FIELD] = {0xF1A8C9ED7B96C4AB, 0x
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x2E1EB8ED8C1C8C94, 0x6CFE456B25DBE01, 0x1EB54C3E8010F57A, 0x4B222D95FC81619D, 0xF99EBD204D501496, 0xC18348F9B629361,
0xC29E9A16BEDE6F96, 0x3B39F30163DAD41D, 0x807D3D1ECF2AC04E, 0xE088443F222A4988, 0x61B49A7524F1EA12, 0x41BF31133104};
0xC29E9A16BEDE6F96, 0x3B39F30163DAD41D, 0x807D3D1ECF2AC04E, 0xE088443F222A4988, 0x61B49A7524F1EA12, 0x41BF31133104
};
/* Full 3-torsion for Bob on A = 0, expressed in Montgomery representation */
static const uint64_t B_gen_3_tors[16 * NWORDS64_FIELD] = {0x7BB7A4A07B0788DC, 0xDC36A3F6607B21B0, 0x4750E18EE74CF2F0, 0x464E319D0B7AB806, 0xC25AA44C04F758FF, 0x392E8521A46E0A68,
@ -133,18 +141,22 @@ static const uint64_t B_gen_3_tors[16 * NWORDS64_FIELD] = {0x7BB7A4A07B0788DC, 0
0xA8C40A6A4ACECF3A, 0xE988877E7DF4D938, 0xC2353D8E5C2F0BAB, 0xC4758A5B1437A358, 0xC5CEE9FD3A3B088D, 0x86B2876D6520F51,
0xD31476314E3DAD08, 0x517E8096137AFBC9, 0xE52ADD7D2B85BB6C, 0x43A92AC98B1E5F2B, 0x4F32E4103B80C703, 0x68BCEB2391D2,
0xA8C40A6A4ACECF3A, 0xE988877E7DF4D938, 0xC2353D8E5C2F0BAB, 0xC4758A5B1437A358, 0xC5CEE9FD3A3B088D, 0x86B2876D6520F51,
0xD31476314E3DAD08, 0x517E8096137AFBC9, 0xE52ADD7D2B85BB6C, 0x43A92AC98B1E5F2B, 0x4F32E4103B80C703, 0x68BCEB2391D2};
0xD31476314E3DAD08, 0x517E8096137AFBC9, 0xE52ADD7D2B85BB6C, 0x43A92AC98B1E5F2B, 0x4F32E4103B80C703, 0x68BCEB2391D2
};
/* Pre-computed pairing ReducedTatePairing(R0,S3,lB^eB) on A = 0 */
static const uint64_t g_R_S_im[NWORDS64_FIELD] = {0xCB6E5ADE9CD78AF1, 0x40F3DD4D50CE0E29, 0x38109C203BF27F5B, 0x50A4863D3A9F473A, 0x518C38F09EC0418E, 0xC2429D6AC98DE417,
0x1A2DC3684817A3CB, 0xF7E83EC334E40005, 0xC560B1CA4C837125, 0xCECA2F86BEB1A124, 0x563DDE23E947A71E, 0x34BDF9FF47AA};
0x1A2DC3684817A3CB, 0xF7E83EC334E40005, 0xC560B1CA4C837125, 0xCECA2F86BEB1A124, 0x563DDE23E947A71E, 0x34BDF9FF47AA
};
// Montgomery constant Montgomery_R2 = (2^768)^2 mod p751
static const uint64_t Montgomery_R2[NWORDS64_FIELD] = {0x233046449DAD4058, 0xDB010161A696452A, 0x5E36941472E3FD8E, 0xF40BFE2082A2E706, 0x4932CCA8904F8751, 0x1F735F1F1EE7FC81,
0xA24F4D80C1048E18, 0xB56C383CCDB607C5, 0x441DD47B735F9C90, 0x5673ED2C6A6AC82A, 0x06C905261132294B, 0x000041AD830F1F35};
0xA24F4D80C1048E18, 0xB56C383CCDB607C5, 0x441DD47B735F9C90, 0x5673ED2C6A6AC82A, 0x06C905261132294B, 0x000041AD830F1F35
};
// Value one in Montgomery representation
static const uint64_t Montgomery_one[NWORDS64_FIELD] = {0x00000000000249ad, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x8310000000000000,
0x5527b1e4375c6c66, 0x697797bf3f4f24d0, 0xc89db7b2ac5c4e2e, 0x4ca4b439d2076956, 0x10f7926c7512c7e9, 0x00002d5b24bce5e2};
0x5527b1e4375c6c66, 0x697797bf3f4f24d0, 0xc89db7b2ac5c4e2e, 0x4ca4b439d2076956, 0x10f7926c7512c7e9, 0x00002d5b24bce5e2
};
// constant Montgomery_RB1 = (2^NBITS_ORDER)^2 mod Bob_order
static const uint64_t Montgomery_RB1[NWORDS64_FIELD] = {0x1A55482318541298, 0x70A6370DFA12A03, 0xCB1658E0E3823A40, 0xB3B7384EB5DEF3F9, 0xCBCA952F7006EA33, 0x569EF8EC94864C};
@ -155,42 +167,47 @@ static const uint64_t Montgomery_RB2[NWORDS64_FIELD] = {0x48062A91D3AB563D, 0x6C
// 1/3 mod p
static const uint64_t threeinv[NWORDS64_FIELD] = {0x555555555556188F, 0x5555555555555555, 0x5555555555555555, 0x5555555555555555,
0x5555555555555555, 0x8105555555555555, 0x1C6290A167C97977, 0xCDD287EA6A6FB6F0,
0x42DF3D3B8EC96F64, 0x198C3C1346027872, 0xB0528624270642A3, 0xF1E61944CA0};
0x42DF3D3B8EC96F64, 0x198C3C1346027872, 0xB0528624270642A3, 0xF1E61944CA0
};
// Fixed parameters for isogeny tree computation
static const unsigned int strat_Alice[MAX_Alice - 1] = {
80, 48, 27, 15, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 7, 4, 2, 1, 1, 2, 1,
1, 3, 2, 1, 1, 1, 1, 12, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 5, 3, 2, 1, 1,
1, 1, 2, 1, 1, 1, 21, 12, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 5, 3, 2, 1,
1, 1, 1, 2, 1, 1, 1, 9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1,
33, 20, 12, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 5, 3, 2, 1, 1, 1, 1, 2, 1,
1, 1, 8, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 2, 1, 1, 16, 8, 4, 2, 1, 1,
1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1};
80, 48, 27, 15, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 7, 4, 2, 1, 1, 2, 1,
1, 3, 2, 1, 1, 1, 1, 12, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 5, 3, 2, 1, 1,
1, 1, 2, 1, 1, 1, 21, 12, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 5, 3, 2, 1,
1, 1, 1, 2, 1, 1, 1, 9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1,
33, 20, 12, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 5, 3, 2, 1, 1, 1, 1, 2, 1,
1, 1, 8, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 2, 1, 1, 16, 8, 4, 2, 1, 1,
1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1
};
static const unsigned int strat_Bob[MAX_Bob - 1] = {
112, 63, 32, 16, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1,
1, 4, 2, 1, 1, 2, 1, 1, 16, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2,
1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 31, 16, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2,
1, 1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 15, 8, 4, 2, 1, 1, 2, 1, 1, 4,
2, 1, 1, 2, 1, 1, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 49, 31, 16, 8, 4, 2,
1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1,
15, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1,
1, 1, 1, 21, 12, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 5, 3, 2, 1, 1, 1, 1,
2, 1, 1, 1, 9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1};
112, 63, 32, 16, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1,
1, 4, 2, 1, 1, 2, 1, 1, 16, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2,
1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 31, 16, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2,
1, 1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 15, 8, 4, 2, 1, 1, 2, 1, 1, 4,
2, 1, 1, 2, 1, 1, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, 1, 49, 31, 16, 8, 4, 2,
1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1,
15, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 7, 4, 2, 1, 1, 2, 1, 1, 3, 2, 1,
1, 1, 1, 21, 12, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 5, 3, 2, 1, 1, 1, 1,
2, 1, 1, 1, 9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1
};
// Fixed traversal strategies for Pohlig-Hellman discrete logs
static const unsigned int ph2_path[PLEN_2] = { // w_2 = 4
0, 0, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 8, 9, 9, 9, 10, 11, 12, 13, 13, 13, 14,
14, 15, 16, 17, 18, 19, 19, 19, 19, 20, 21, 22, 22, 23, 24, 25, 26, 27, 27,
28, 28, 28, 28, 28, 29, 30, 31, 32, 33, 34, 34, 35, 36, 37, 38, 39, 40, 40,
40, 40, 41, 42, 42, 42, 42, 42, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
52, 53, 54, 55, 56, 57, 58, 59, 59, 59, 59, 59, 59, 59};
0, 0, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 8, 9, 9, 9, 10, 11, 12, 13, 13, 13, 14,
14, 15, 16, 17, 18, 19, 19, 19, 19, 20, 21, 22, 22, 23, 24, 25, 26, 27, 27,
28, 28, 28, 28, 28, 29, 30, 31, 32, 33, 34, 34, 35, 36, 37, 38, 39, 40, 40,
40, 40, 41, 42, 42, 42, 42, 42, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
52, 53, 54, 55, 56, 57, 58, 59, 59, 59, 59, 59, 59, 59
};
static const unsigned int ph3_path[PLEN_3] = { // w_3 = 5
0, 0, 1, 2, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 11, 11, 12, 13, 14, 15, 15, 16,
17, 18, 19, 20, 20, 20, 21, 22, 23, 24, 25, 26, 26, 26, 26, 27, 28, 29, 30,
31, 32, 33, 34, 34, 34, 34};
0, 0, 1, 2, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 11, 11, 12, 13, 14, 15, 15, 16,
17, 18, 19, 20, 20, 20, 21, 22, 23, 24, 25, 26, 26, 26, 26, 27, 28, 29, 30,
31, 32, 33, 34, 34, 34, 34
};
// Entangled bases related static tables and parameters
@ -202,150 +219,157 @@ static const unsigned int ph3_path[PLEN_3] = { // w_3 = 5
// A table of size 20 for values v = 1/(1+U*r^2) where U = 4+i
static const uint64_t u_entang[2 * NWORDS64_FIELD] = {
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x000000000004935a, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0620000000000000,
0xaa4f63c86eb8d8cd, 0xd2ef2f7e7e9e49a0, 0x913b6f6558b89c5c, 0x99496873a40ed2ad, 0x21ef24d8ea258fd2, 0x00005ab64979cbc4};
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x000000000004935a, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0620000000000000,
0xaa4f63c86eb8d8cd, 0xd2ef2f7e7e9e49a0, 0x913b6f6558b89c5c, 0x99496873a40ed2ad, 0x21ef24d8ea258fd2, 0x00005ab64979cbc4
};
static const uint64_t u0_entang[2 * NWORDS64_FIELD] = {
0x00000000000249ad, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x8310000000000000,
0x5527b1e4375c6c66, 0x697797bf3f4f24d0, 0xc89db7b2ac5c4e2e, 0x4ca4b439d2076956, 0x10f7926c7512c7e9, 0x00002d5b24bce5e2,
0x00000000000249ad, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x8310000000000000,
0x5527b1e4375c6c66, 0x697797bf3f4f24d0, 0xc89db7b2ac5c4e2e, 0x4ca4b439d2076956, 0x10f7926c7512c7e9, 0x00002d5b24bce5e2};
0x00000000000249ad, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x8310000000000000,
0x5527b1e4375c6c66, 0x697797bf3f4f24d0, 0xc89db7b2ac5c4e2e, 0x4ca4b439d2076956, 0x10f7926c7512c7e9, 0x00002d5b24bce5e2,
0x00000000000249ad, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x8310000000000000,
0x5527b1e4375c6c66, 0x697797bf3f4f24d0, 0xc89db7b2ac5c4e2e, 0x4ca4b439d2076956, 0x10f7926c7512c7e9, 0x00002d5b24bce5e2
};
// Tables for quadratic residues and quadratic non residues v with 17 elements each.
static const uint64_t table_r_qr[][NWORDS64_FIELD] =
{{0x249AD, 0x0, 0x0, 0x0, 0x0, 0x8310000000000000, 0x5527B1E4375C6C66, 0x697797BF3F4F24D0, 0xC89DB7B2AC5C4E2E, 0x4CA4B439D2076956, 0x10F7926C7512C7E9, 0x2D5B24BCE5E2},
{0x926B5, 0x0, 0x0, 0x0, 0x0, 0x1D90000000000000, 0x70B2310B937938F1, 0xCB48C3E2E944C6CA, 0x1A284662DA855042, 0xAD301BE2EB6B4E13, 0x35CBB9123C90433E, 0x4586BDB1A06C},
{0xDBA10, 0x0, 0x0, 0x0, 0x0, 0x3500000000000000, 0x3714FE4EB8399915, 0xC3A2584753EB43F4, 0xA3151D605C520428, 0xC116CF5232C7C978, 0x49A84D4B8EFAF6AA, 0x305731E97514},
{0x1003BD, 0x0, 0x0, 0x0, 0x0, 0xB810000000000000, 0x8C3CB032EF96057B, 0x2D19F006933A68C4, 0x6BB2D51308AE5257, 0xDBB838C04CF32CF, 0x5A9FDFB8040DBE94, 0x5DB256A65AF6},
{0x124D6B, 0x0, 0x0, 0x0, 0x0, 0x4C70000000000000, 0xFD77CB91DCF9F939, 0xBBFBECABBE91C11D, 0x2C01F45DDE1EB80E, 0xD4FD82C17A2444DE, 0x5D84E184E165AA16, 0x1B27A62149BC},
{0x149718, 0x0, 0x0, 0x0, 0x0, 0xCF80000000000000, 0x529F7D761456659F, 0x2573846AFDE0E5EE, 0xF49FAC108A7B063D, 0x21A236FB4C2BAE34, 0x6E7C73F156787200, 0x4882CADE2F9E},
{0x192A73, 0x0, 0x0, 0x0, 0x0, 0xE6F0000000000000, 0x19024AB93916C5C3, 0x1DCD18CF68876318, 0x7D8C830E0C47BA23, 0x3588EA6A9388299A, 0x8259082AA8E3256C, 0x33533F160446},
{0x1DBDCE, 0x0, 0x0, 0x0, 0x0, 0xFE60000000000000, 0xDF6517FC5DD725E7, 0x1626AD33D32DE041, 0x6795A0B8E146E09, 0x496F9DD9DAE4A500, 0x96359C63FB4DD8D8, 0x1E23B34DD8EE},
{0x249AD6, 0x0, 0x0, 0x0, 0x0, 0x98E0000000000000, 0xFAEF9723B9F3F272, 0x77F7D9577D23823B, 0x5803E8BBBC3D701D, 0xA9FB0582F44889BC, 0xBB09C309C2CB542D, 0x364F4C429378},
{0x292E31, 0x0, 0x0, 0x0, 0x0, 0xB050000000000000, 0xC1526466DEB45296, 0x70516DBBE7C9FF65, 0xE0F0BFB93E0A2403, 0xBDE1B8F23BA50521, 0xCEE6574315360799, 0x211FC07A6820},
{0x2B77DE, 0x0, 0x0, 0x0, 0x0, 0x3360000000000000, 0x167A164B1610BEFD, 0xD9C9057B27192436, 0xA98E776BEA667231, 0xA866D2C0DAC6E78, 0xDFDDE9AF8A48CF83, 0x4E7AE5374E02},
{0x2DC18C, 0x0, 0x0, 0x0, 0x0, 0xC7C0000000000000, 0x87B531AA0374B2BA, 0x68AB022052707C8F, 0x69DD96B6BFD6D7E9, 0xD1C86C6183018087, 0xE2C2EB7C67A0BB05, 0xBF034B23CC8},
{0x300B39, 0x0, 0x0, 0x0, 0x0, 0x4AD0000000000000, 0xDCDCE38E3AD11F21, 0xD22299DF91BFA15F, 0x327B4E696C332617, 0x1E6D209B5508E9DE, 0xF3BA7DE8DCB382EF, 0x394B596F22AA},
{0x3254E6, 0x0, 0x0, 0x0, 0x0, 0xCDE0000000000000, 0x32049572722D8B87, 0x3B9A319ED10EC630, 0xFB19061C188F7446, 0x6B11D4D527105334, 0x4B2105551C64AD8, 0x66A67E2C088D},
{0x349E94, 0x0, 0x0, 0x0, 0x0, 0x6240000000000000, 0xA33FB0D15F917F45, 0xCA7C2E43FC661E89, 0xBB682566EDFFD9FD, 0x3253D40A9C656543, 0x79712222F1E365B, 0x241BCDA6F753},
{0x3B7B9C, 0x0, 0x0, 0x0, 0x0, 0xFCC0000000000000, 0xBECA2FF8BBAE4BCF, 0x2C4D5A67A65BC083, 0xCF2B4171C28DC12, 0x92DF3BB3B5C94A00, 0x2C6B38C7F69BB1B0, 0x3C47669BB1DD},
{0x3DC549, 0x0, 0x0, 0x0, 0x0, 0x7FD0000000000000, 0x13F1E1DCF30AB836, 0x95C4F226E5AAE554, 0xD5906BC9C8852A40, 0xDF83EFED87D0B356, 0x3D62CB346BAE7999, 0x69A28B5897BF}};
static const uint64_t table_r_qr[][NWORDS64_FIELD] = {
{0x249AD, 0x0, 0x0, 0x0, 0x0, 0x8310000000000000, 0x5527B1E4375C6C66, 0x697797BF3F4F24D0, 0xC89DB7B2AC5C4E2E, 0x4CA4B439D2076956, 0x10F7926C7512C7E9, 0x2D5B24BCE5E2},
{0x926B5, 0x0, 0x0, 0x0, 0x0, 0x1D90000000000000, 0x70B2310B937938F1, 0xCB48C3E2E944C6CA, 0x1A284662DA855042, 0xAD301BE2EB6B4E13, 0x35CBB9123C90433E, 0x4586BDB1A06C},
{0xDBA10, 0x0, 0x0, 0x0, 0x0, 0x3500000000000000, 0x3714FE4EB8399915, 0xC3A2584753EB43F4, 0xA3151D605C520428, 0xC116CF5232C7C978, 0x49A84D4B8EFAF6AA, 0x305731E97514},
{0x1003BD, 0x0, 0x0, 0x0, 0x0, 0xB810000000000000, 0x8C3CB032EF96057B, 0x2D19F006933A68C4, 0x6BB2D51308AE5257, 0xDBB838C04CF32CF, 0x5A9FDFB8040DBE94, 0x5DB256A65AF6},
{0x124D6B, 0x0, 0x0, 0x0, 0x0, 0x4C70000000000000, 0xFD77CB91DCF9F939, 0xBBFBECABBE91C11D, 0x2C01F45DDE1EB80E, 0xD4FD82C17A2444DE, 0x5D84E184E165AA16, 0x1B27A62149BC},
{0x149718, 0x0, 0x0, 0x0, 0x0, 0xCF80000000000000, 0x529F7D761456659F, 0x2573846AFDE0E5EE, 0xF49FAC108A7B063D, 0x21A236FB4C2BAE34, 0x6E7C73F156787200, 0x4882CADE2F9E},
{0x192A73, 0x0, 0x0, 0x0, 0x0, 0xE6F0000000000000, 0x19024AB93916C5C3, 0x1DCD18CF68876318, 0x7D8C830E0C47BA23, 0x3588EA6A9388299A, 0x8259082AA8E3256C, 0x33533F160446},
{0x1DBDCE, 0x0, 0x0, 0x0, 0x0, 0xFE60000000000000, 0xDF6517FC5DD725E7, 0x1626AD33D32DE041, 0x6795A0B8E146E09, 0x496F9DD9DAE4A500, 0x96359C63FB4DD8D8, 0x1E23B34DD8EE},
{0x249AD6, 0x0, 0x0, 0x0, 0x0, 0x98E0000000000000, 0xFAEF9723B9F3F272, 0x77F7D9577D23823B, 0x5803E8BBBC3D701D, 0xA9FB0582F44889BC, 0xBB09C309C2CB542D, 0x364F4C429378},
{0x292E31, 0x0, 0x0, 0x0, 0x0, 0xB050000000000000, 0xC1526466DEB45296, 0x70516DBBE7C9FF65, 0xE0F0BFB93E0A2403, 0xBDE1B8F23BA50521, 0xCEE6574315360799, 0x211FC07A6820},
{0x2B77DE, 0x0, 0x0, 0x0, 0x0, 0x3360000000000000, 0x167A164B1610BEFD, 0xD9C9057B27192436, 0xA98E776BEA667231, 0xA866D2C0DAC6E78, 0xDFDDE9AF8A48CF83, 0x4E7AE5374E02},
{0x2DC18C, 0x0, 0x0, 0x0, 0x0, 0xC7C0000000000000, 0x87B531AA0374B2BA, 0x68AB022052707C8F, 0x69DD96B6BFD6D7E9, 0xD1C86C6183018087, 0xE2C2EB7C67A0BB05, 0xBF034B23CC8},
{0x300B39, 0x0, 0x0, 0x0, 0x0, 0x4AD0000000000000, 0xDCDCE38E3AD11F21, 0xD22299DF91BFA15F, 0x327B4E696C332617, 0x1E6D209B5508E9DE, 0xF3BA7DE8DCB382EF, 0x394B596F22AA},
{0x3254E6, 0x0, 0x0, 0x0, 0x0, 0xCDE0000000000000, 0x32049572722D8B87, 0x3B9A319ED10EC630, 0xFB19061C188F7446, 0x6B11D4D527105334, 0x4B2105551C64AD8, 0x66A67E2C088D},
{0x349E94, 0x0, 0x0, 0x0, 0x0, 0x6240000000000000, 0xA33FB0D15F917F45, 0xCA7C2E43FC661E89, 0xBB682566EDFFD9FD, 0x3253D40A9C656543, 0x79712222F1E365B, 0x241BCDA6F753},
{0x3B7B9C, 0x0, 0x0, 0x0, 0x0, 0xFCC0000000000000, 0xBECA2FF8BBAE4BCF, 0x2C4D5A67A65BC083, 0xCF2B4171C28DC12, 0x92DF3BB3B5C94A00, 0x2C6B38C7F69BB1B0, 0x3C47669BB1DD},
{0x3DC549, 0x0, 0x0, 0x0, 0x0, 0x7FD0000000000000, 0x13F1E1DCF30AB836, 0x95C4F226E5AAE554, 0xD5906BC9C8852A40, 0xDF83EFED87D0B356, 0x3D62CB346BAE7999, 0x69A28B5897BF}
};
static const uint64_t table_r_qnr[17][NWORDS64_FIELD] =
{{0x4935A, 0x0, 0x0, 0x0, 0x0, 0x620000000000000, 0xAA4F63C86EB8D8CD, 0xD2EF2F7E7E9E49A0, 0x913B6F6558B89C5C, 0x99496873A40ED2AD, 0x21EF24D8EA258FD2, 0x5AB64979CBC4},
{0x6DD08, 0x0, 0x0, 0x0, 0x0, 0x9A80000000000000, 0x1B8A7F275C1CCC8A, 0x61D12C23A9F5A1FA, 0x518A8EB02E290214, 0x608B67A91963E4BC, 0x24D426A5C77D7B55, 0x182B98F4BA8A},
{0xB7063, 0x0, 0x0, 0x0, 0x0, 0xB1F0000000000000, 0xE1ED4C6A80DD2CAE, 0x5A2AC088149C1F23, 0xDA7765ADAFF5B5FA, 0x74721B1860C06021, 0x38B0BADF19E82EC1, 0x2FC0D2C8F32},
{0x16E0C6, 0x0, 0x0, 0x0, 0x0, 0x63E0000000000000, 0xC3DA98D501BA595D, 0xB455811029383E47, 0xB4EECB5B5FEB6BF4, 0xE8E43630C180C043, 0x716175BE33D05D82, 0x5F81A591E64},
{0x1B7420, 0x0, 0x0, 0x0, 0x0, 0x6A00000000000000, 0x6E29FC9D7073322A, 0x8744B08EA7D687E8, 0x462A3AC0B8A40851, 0x822D9EA4658F92F1, 0x93509A971DF5ED55, 0x60AE63D2EA28},
{0x20077B, 0x0, 0x0, 0x0, 0x0, 0x8170000000000000, 0x348CC9E09533924E, 0x7F9E44F3127D0512, 0xCF1711BE3A70BC37, 0x96145213ACEC0E56, 0xA72D2ED07060A0C1, 0x4B7ED80ABED0},
{0x225129, 0x0, 0x0, 0x0, 0x0, 0x15D0000000000000, 0xA5C7E53F8297860C, 0xE8041983DD45D6B, 0x8F6631090FE121EF, 0x5D56514922412065, 0xAA12309D4DB88C44, 0x8F42785AD96},
{0x26E483, 0x0, 0x0, 0x0, 0x0, 0x1BF0000000000000, 0x50174907F1505ED9, 0xE16F7116BC72A70C, 0x20A1A06E6899BE4B, 0xF69FB9BCC64FF313, 0xCC01557637DE1C16, 0x63AA70FF795A},
{0x36E841, 0x0, 0x0, 0x0, 0x0, 0xE550000000000000, 0xF86762B596EDEBAB, 0x33F3C6033BB54359, 0x8405DD199A5C282C, 0x7EF888446E6CCE9A, 0x188EA48EA430FE44, 0x5176F263DD35},
{0x3931EF, 0x0, 0x0, 0x0, 0x0, 0x79B0000000000000, 0x69A27E148451DF69, 0xC2D5C2A8670C9BB3, 0x4454FC646FCC8DE3, 0x463A8779E3C1E0A9, 0x1B73A65B8188E9C7, 0xEEC41DECBFB},
{0x400EF7, 0x0, 0x0, 0x0, 0x0, 0x1430000000000000, 0x852CFD3BE06EABF4, 0x24A6EECC11023DAD, 0x95DF8B149DF58FF8, 0xA6C5EF22FD25C565, 0x4047CD014906651C, 0x2717DAD38685},
{0x4258A4, 0x0, 0x0, 0x0, 0x0, 0x9740000000000000, 0xDA54AF2017CB185A, 0x8E1E868B5051627D, 0x5E7D42C74A51DE26, 0xF36AA35CCF2D2EBC, 0x513F5F6DBE192D05, 0x5472FF906C67},
{0x44A252, 0x0, 0x0, 0x0, 0x0, 0x2BA0000000000000, 0x4B8FCA7F052F0C18, 0x1D0083307BA8BAD7, 0x1ECC62121FC243DE, 0xBAACA292448240CB, 0x5424613A9B711888, 0x11E84F0B5B2D},
{0x46EBFF, 0x0, 0x0, 0x0, 0x0, 0xAEB0000000000000, 0xA0B77C633C8B787E, 0x86781AEFBAF7DFA7, 0xE76A19C4CC1E920C, 0x75156CC1689AA21, 0x651BF3A71083E072, 0x3F4373C8410F},
{0x4935AC, 0x0, 0x0, 0x0, 0x0, 0x31C0000000000000, 0xF5DF2E4773E7E4E5, 0xEFEFB2AEFA470477, 0xB007D177787AE03A, 0x53F60B05E8911378, 0x761386138596A85B, 0x6C9E988526F1},
{0x4DC907, 0x0, 0x0, 0x0, 0x0, 0x4930000000000000, 0xBC41FB8A98A84509, 0xE849471364ED81A1, 0x38F4A874FA479420, 0x67DCBE752FED8EDE, 0x89F01A4CD8015BC7, 0x576F0CBCFB99},
{0x525C62, 0x0, 0x0, 0x0, 0x0, 0x60A0000000000000, 0x82A4C8CDBD68A52D, 0xE0A2DB77CF93FECB, 0xC1E17F727C144806, 0x7BC371E4774A0A43, 0x9DCCAE862A6C0F33, 0x423F80F4D041}};
static const uint64_t table_r_qnr[17][NWORDS64_FIELD] = {
{0x4935A, 0x0, 0x0, 0x0, 0x0, 0x620000000000000, 0xAA4F63C86EB8D8CD, 0xD2EF2F7E7E9E49A0, 0x913B6F6558B89C5C, 0x99496873A40ED2AD, 0x21EF24D8EA258FD2, 0x5AB64979CBC4},
{0x6DD08, 0x0, 0x0, 0x0, 0x0, 0x9A80000000000000, 0x1B8A7F275C1CCC8A, 0x61D12C23A9F5A1FA, 0x518A8EB02E290214, 0x608B67A91963E4BC, 0x24D426A5C77D7B55, 0x182B98F4BA8A},
{0xB7063, 0x0, 0x0, 0x0, 0x0, 0xB1F0000000000000, 0xE1ED4C6A80DD2CAE, 0x5A2AC088149C1F23, 0xDA7765ADAFF5B5FA, 0x74721B1860C06021, 0x38B0BADF19E82EC1, 0x2FC0D2C8F32},
{0x16E0C6, 0x0, 0x0, 0x0, 0x0, 0x63E0000000000000, 0xC3DA98D501BA595D, 0xB455811029383E47, 0xB4EECB5B5FEB6BF4, 0xE8E43630C180C043, 0x716175BE33D05D82, 0x5F81A591E64},
{0x1B7420, 0x0, 0x0, 0x0, 0x0, 0x6A00000000000000, 0x6E29FC9D7073322A, 0x8744B08EA7D687E8, 0x462A3AC0B8A40851, 0x822D9EA4658F92F1, 0x93509A971DF5ED55, 0x60AE63D2EA28},
{0x20077B, 0x0, 0x0, 0x0, 0x0, 0x8170000000000000, 0x348CC9E09533924E, 0x7F9E44F3127D0512, 0xCF1711BE3A70BC37, 0x96145213ACEC0E56, 0xA72D2ED07060A0C1, 0x4B7ED80ABED0},
{0x225129, 0x0, 0x0, 0x0, 0x0, 0x15D0000000000000, 0xA5C7E53F8297860C, 0xE8041983DD45D6B, 0x8F6631090FE121EF, 0x5D56514922412065, 0xAA12309D4DB88C44, 0x8F42785AD96},
{0x26E483, 0x0, 0x0, 0x0, 0x0, 0x1BF0000000000000, 0x50174907F1505ED9, 0xE16F7116BC72A70C, 0x20A1A06E6899BE4B, 0xF69FB9BCC64FF313, 0xCC01557637DE1C16, 0x63AA70FF795A},
{0x36E841, 0x0, 0x0, 0x0, 0x0, 0xE550000000000000, 0xF86762B596EDEBAB, 0x33F3C6033BB54359, 0x8405DD199A5C282C, 0x7EF888446E6CCE9A, 0x188EA48EA430FE44, 0x5176F263DD35},
{0x3931EF, 0x0, 0x0, 0x0, 0x0, 0x79B0000000000000, 0x69A27E148451DF69, 0xC2D5C2A8670C9BB3, 0x4454FC646FCC8DE3, 0x463A8779E3C1E0A9, 0x1B73A65B8188E9C7, 0xEEC41DECBFB},
{0x400EF7, 0x0, 0x0, 0x0, 0x0, 0x1430000000000000, 0x852CFD3BE06EABF4, 0x24A6EECC11023DAD, 0x95DF8B149DF58FF8, 0xA6C5EF22FD25C565, 0x4047CD014906651C, 0x2717DAD38685},
{0x4258A4, 0x0, 0x0, 0x0, 0x0, 0x9740000000000000, 0xDA54AF2017CB185A, 0x8E1E868B5051627D, 0x5E7D42C74A51DE26, 0xF36AA35CCF2D2EBC, 0x513F5F6DBE192D05, 0x5472FF906C67},
{0x44A252, 0x0, 0x0, 0x0, 0x0, 0x2BA0000000000000, 0x4B8FCA7F052F0C18, 0x1D0083307BA8BAD7, 0x1ECC62121FC243DE, 0xBAACA292448240CB, 0x5424613A9B711888, 0x11E84F0B5B2D},
{0x46EBFF, 0x0, 0x0, 0x0, 0x0, 0xAEB0000000000000, 0xA0B77C633C8B787E, 0x86781AEFBAF7DFA7, 0xE76A19C4CC1E920C, 0x75156CC1689AA21, 0x651BF3A71083E072, 0x3F4373C8410F},
{0x4935AC, 0x0, 0x0, 0x0, 0x0, 0x31C0000000000000, 0xF5DF2E4773E7E4E5, 0xEFEFB2AEFA470477, 0xB007D177787AE03A, 0x53F60B05E8911378, 0x761386138596A85B, 0x6C9E988526F1},
{0x4DC907, 0x0, 0x0, 0x0, 0x0, 0x4930000000000000, 0xBC41FB8A98A84509, 0xE849471364ED81A1, 0x38F4A874FA479420, 0x67DCBE752FED8EDE, 0x89F01A4CD8015BC7, 0x576F0CBCFB99},
{0x525C62, 0x0, 0x0, 0x0, 0x0, 0x60A0000000000000, 0x82A4C8CDBD68A52D, 0xE0A2DB77CF93FECB, 0xC1E17F727C144806, 0x7BC371E4774A0A43, 0x9DCCAE862A6C0F33, 0x423F80F4D041}
};
static const uint64_t table_v_qr[TABLE_V_LEN][NWORDS64_FIELD] =
{{0xCCCCCCCCCCCD41EF, 0xCCCCCCCCCCCCCCCC, 0xCCCCCCCCCCCCCCCC, 0xCCCCCCCCCCCCCCCC, 0xCCCCCCCCCCCCCCCC, 0x467CCCCCCCCCCCCC, 0x5CCF962F575DF8B, 0x3953C2CA47D95926, 0xC50BC81A120A6C9F, 0xDE486C73B57C04C7, 0x3C38F0BBEDB4E68A, 0x35D48FD9C405},
{0x6666666666657C21, 0x6666666666666666, 0x6666666666666666, 0x6666666666666666, 0x6666666666666666, 0x61B6666666666666, 0xD852A3BF5F0CB992, 0x67EE158584451A2A, 0x7E370833B2D70F38, 0xC8D1DC1CF1BA4DB8, 0x95A0AF27BC510F50, 0x43CB58E6F11},
{0xB891DB891DB8926D, 0xDB891DB891DB891D, 0x1DB891DB891DB891, 0x91DB891DB891DB89, 0x891DB891DB891DB8, 0xB7A1DB891DB891DB, 0x7667EA3E359A528F, 0x920F68111BC2395B, 0x73153DF2CE971E2C, 0x16EDA0D863AC7DA5, 0xBF837289A3FC18BF, 0x5ADF5C37BA11},
{0xEDC48EDC48EDB246, 0x8EDC48EDC48EDC48, 0x48EDC48EDC48EDC4, 0xC48EDC48EDC48EDC, 0xDC48EDC48EDC48ED, 0x49A48EDC48EDC48E, 0x590A01C2CFF1EF31, 0xF144BE828EE398A4, 0x7553BC320111D67F, 0xAE524764F48D28A2, 0x7D745F00E9774A86, 0x16C21BBD6A1},
{0x5E40E05A0E84063C, 0x1F4D776F0A51A9CB, 0xCB5E40E05A0E8406, 0x61F4D776F0A51A9, 0xA9CB5E40E05A0E84, 0x72C61F4D776F0A51, 0x618B216FB9C76A1E, 0xE22409F266B16463, 0x894A7D245553FD6B, 0x4E89F364CCE00FA7, 0x77A8C743F3083EC9, 0x188BE18D4AC5},
{0x7DC0E6ABEADE3F10, 0x323668C519083ECD, 0xCD7DC0E6ABEADE47, 0x47323668C519083E, 0x3ECD7DC0E6ABEADE, 0xA347323668C51908, 0xCFA800E85F71B1FE, 0xF36E5745D988B7A, 0xE7F654456F1F4116, 0x3F5EDBEC2C210D61, 0x39B0FEDD215C1DCA, 0x1705E4626A37},
{0x791C39AD37694088, 0x40791C39AD376940, 0x6940791C39AD3769, 0x376940791C39AD37, 0xAD376940791C39AD, 0x6C2D376940791C39, 0x4A463885B9946D81, 0x736B37A93397FE42, 0x3874F55B29BB4D54, 0x5F7A8A5F8D7543C5, 0x228CCBA8F76BD619, 0x5096624D7492},
{0xA331EBB0C9B54BA9, 0x51A331EBB0C9B551, 0xB551A331EBB0C9B5, 0xC9B551A331EBB0C9, 0xB0C9B551A331EBB0, 0xC980C9B551A331EB, 0xC7BC1BC679178B4E, 0x7072B575C98A5F98, 0xB10657E6A1B9DEA2, 0x71773BA18E92437A, 0xAD4025945D8B2AB8, 0x2F2C83A4E8D6},
{0x732233773223377C, 0x3773223377322337, 0x2337732233773223, 0x3223377322337732, 0x7732233773223377, 0xC637322337732233, 0x2695C5C06B69B3F6, 0x2330B3C47A0D9F3, 0x1FF319B45BEC27C0, 0xA128906C609EE6B9, 0x736A7518122E449F, 0x1FCE86244E63},
{0x6EE64466EE6441DB, 0x466EE64466EE6446, 0x64466EE64466EE64, 0xEE64466EE64466EE, 0x66EE64466EE64466, 0x63D6EE64466EE644, 0xA64EE10DFC0F7507, 0x7E19CCA11263939B, 0x39CF2CD41A04B92C, 0xB2FBF371165340D9, 0x53745B07D6DF8B00, 0x44F4C0618554},
{0x70E5437D550C15E9, 0x514AB52CDC183AC2, 0xA4D63DFA7AA6594A, 0x46DAD39BC3F3F19, 0x82FD5B4A38522B72, 0xAD58A5AA7E8D2ECF, 0x523BAAB70A135BE2, 0x45782546050175F7, 0xB24F33FAA2472B55, 0xEBA7A14C1F8593CD, 0x20600FBAB2D24E65, 0x133D309F7EC7},
{0x8EEB4AB02E5A2272, 0x8EB9599CB8AAD0F4, 0xB06CC77E62BB7EF8, 0x32986176DFFA11C5, 0x1BAC3B085C0081D9, 0x69272A1BEAA860AF, 0xE41E6EBFB6ED0D08, 0xF255608B042DB67E, 0x1279C6C0D0C40109, 0x76B7BA4E30FA03B6, 0xD3DDD4F6F5A7EB7, 0x106A8E48CD0F},
{0xD5120148FEAF2C06, 0x255365F9DAA4C4B8, 0xCC272EFC74777061, 0xD9E68887C98D5C50, 0x383B3424E91729B, 0xE0B5120148FEAF2C, 0x1BE4FA2B9F7CFD78, 0xDA98A1C587680DD9, 0xACC09E7217DDD41D, 0xBAB5E239D699C58C, 0x41FD047089438309, 0x858395E2C66},
{0x94FAC8FF3E686241, 0xB72999CF503E0946, 0x2F59559E717C42A, 0x412EFA3785EBB9F, 0xAD808B51BA81A8AC, 0x4BE4FAC8FF3E6864, 0x8C1AAEA7B9495845, 0x94D196357B071596, 0x4FBF87DA63CFBC99, 0x666394A603DFBB5D, 0xAA328976810C7C69, 0x6AA898DF5E6A},
{0x40E70907368FAAA3, 0x2531EC3903CE9F2C, 0xF8AB9BFACF708D95, 0xD2DE3A9B1838859A, 0x4E47B12D7C682948, 0x281BDC83C4953F02, 0xDE0EF99ABED7AFEA, 0xB81783A3E8034AE6, 0x3E73219AAC32B265, 0xA6F25C569E80F4D3, 0x6961E44D2E61E550, 0x54AF9D7748CE},
{0x4EF61479F650B3CA, 0xE4161CB8F931D792, 0xAD6C0EDA1D651114, 0x96969F3A055F9963, 0xA55811F1BE797DD9, 0xBB36DA0672F2CEF4, 0xBCD0F6F9FFB265C5, 0x868F4BABA3739212, 0xDA96099F90F8EC8D, 0xF6B719FF6C14091F, 0xEF5131B07D9BA208, 0x15F75A78FB86},
{0xB5CA528D6B5CA529, 0xCA528D6B5CA528D6, 0x528D6B5CA528D6B5, 0x8D6B5CA528D6B5CA, 0x6B5CA528D6B5CA52, 0xB27528D6B5CA528D, 0xD7C00A95FC590145, 0x4E4610B31250410D, 0x92EB9C10C371F0FC, 0x71D124AD03784C6D, 0xFBA87309E1A6D857, 0x2DF3B0F268CD},
{0x6B5AE52946B5AD2D, 0x5AE52946B5AE5294, 0xE52946B5AE52946B, 0x2946B5AE52946B5A, 0x46B5AE52946B5AE5, 0xD0BE52946B5AE529, 0x5BEAE3E345C8E7D7, 0x9D2D7059D4BB6A4E, 0x18F7C0F408EA159, 0x4E11D89176651539, 0x48671FC6C152F99C, 0x530CE08D1028},
{0xCE57AA6B0A6E427F, 0x9B8F883433A0EB6A, 0xBD90869A824E3109, 0xD1840719519276EA, 0xF601CD0A72F12455, 0x8904C6A15653D646, 0x72DB02908565884, 0x71294DC40DC2EB13, 0x361608701CEA745E, 0x1279CC6C51A4F800, 0xDD923715582E9EDE, 0x6578E5CC44C5},
{0xB218A10D98E7AC3C, 0x3CAF3BDD50AC19A5, 0x2A2B48E62A13DFAE, 0xA9CE07E98542FDD0, 0x4B70FD8D0D9C06C5, 0x6829379D7BC99C61, 0x57C3D248CC251489, 0x9F1367A307C698E9, 0x2CC0B2B8746361EF, 0x9A6A53D6400CB8EA, 0x7888C0894B30195B, 0x29E026757F97},
{0xB7B49E77DD01B05A, 0xC7FCDE689EA7A30E, 0x3B83E48534D253E7, 0xE1F4F28B24C70D5F, 0xC226AF798CDAE97, 0x29592FFABA44E0BF, 0x451BFFACF7902A0B, 0xEF0C4136DB713262, 0x7F066B8D7CD90C93, 0x193C99BB6A2BD9E4, 0xDCCEB7DD7547E7EE, 0x1BC6242C97DB},
{0xE49911F2B13CA178, 0xF8D4BCF08B36207D, 0x2605805106CF5C4D, 0xBB2BF392469C496A, 0xC6EE51B30BE997A4, 0x3636AEDEA9BE252F, 0x5962BFE5CE1E434D, 0x80A1219F24FBAA71, 0x9727D3F901B9FA59, 0x9C7DB47FBDB8D837, 0x260B21A1EA96DA92, 0x58C7EC9D75A5},
{0x11372FCC7943203A, 0x5C4549B345DE13E1, 0xB35E08AA984D8EEB, 0x9AD22A4F3D9CF45D, 0x84408FBE68108C13, 0xD6F34279BA1D5079, 0xFD86BCE1D485CE9C, 0x7547DCC9E6A72B9A, 0x82BAC6E5640D1B8, 0xA0AA9060525B5FA0, 0x9DF6B6008023369A, 0x64534002FC0F},
{0x338AA1050E3B47F2, 0xA779AFC5AA01E0AA, 0x7A24EAE40DA1607F, 0x2F3BC85F75845B2F, 0xB63ECCFACC4A42BC, 0xB970439A64648442, 0xFC7FE81D54BCBFAD, 0x8F070C333697311A, 0xC3F49A6F3F169CEA, 0x5D4853A9EA5F7ED, 0xD518DE0B200B8454, 0x527415AF5FE1},
{0x29D6C703462657AD, 0xDC60DB370D32F7B9, 0x7ECF292BC2C418DD, 0x37B10E0D29478FC0, 0x2DFAFEF9EA3B8E16, 0xE9716B45FA8908A4, 0x6CB32B342A6375FF, 0xFD73F31AB04928C5, 0xB397940272F73C0C, 0x5B001264620355C2, 0x5803F26169F9945B, 0x5C5620099D9B},
{0xDA0656B84FE5EB1E, 0xBA4CBC548666840D, 0x1A44273AF862539E, 0x1FFD96A7C772BACB, 0x953D86F6FED07774, 0x7BBC68E6D3E03A59, 0xA78131504FEA94B4, 0x5FF580356C9EF9E7, 0xDF4576DB17102D3C, 0xCA73668DEBAABC08, 0xC73232385D81A0CB, 0x14DC1275B692},
{0xE1C98F3C564A49CD, 0x76847854DFFF1979, 0x6DD3A9A2B019D474, 0xFEB9A85944A3C836, 0x4C554E80A25DEBB9, 0xC247DBF7209CBA59, 0xE606E4DA4D403E68, 0x5AABAE35231E6C78, 0x1E08F32D70B4CF5A, 0x8EDD7B4A0D3949FA, 0xA549CBAE571FABD6, 0x345B562BB1C2},
{0x3DDA63D9B718EF13, 0xDB18FF110367AB22, 0xB7A690D61E54A79F, 0xD1FB6E7474B2F230, 0x5D6F299A0CDCA8B4, 0xBDB8418CAF5F5E57, 0x87950067C9C186CF, 0xF190BC388A72A53B, 0x213C2BED23C24CA9, 0xD23020B606F4B8B5, 0xE7CFBF2E0DE63E1D, 0x85488821CA3},
{0x2E87222F0886018B, 0x2006A348352327DC, 0x19561FC0617F066, 0x390FD49917EAD64, 0xC8962E05BE5C859E, 0x9098F7D823688E17, 0xA367361FE7730947, 0x4C6AE2F141441363, 0x6012B07C3CA41E86, 0xB27005C079FEB1B6, 0x825B9BFC26C91F27, 0x3F1183F8513F},
{0xB584B99EC62D9D35, 0xA4912F9464B54407, 0x74A10C6ED11079EF, 0x42C935F4B27768B1, 0x355CC43459FC8F5, 0x83FB4BDA9E4C1B5, 0x362D54FAF7050831, 0xED24CAC0D587AF78, 0x520C08B595DEF623, 0x9C385DB3FD4B1742, 0x12B09C148B913905, 0x4C96EA957BF4},
{0xCCB2CE7886EF239D, 0x47C704F6F492B661, 0x63CDC17F473B3143, 0xE43575F9DEDACC50, 0xED36745A83436E23, 0xB43E3A2A47D36381, 0x6FE523A476BF9F48, 0x82B1F402B3BD2A0, 0xDBE6E728B539ADAE, 0xA37C34807A76FF4E, 0x538EE747772483FB, 0xDB5A5E658A6},
{0xEFAD9377610BEA32, 0xECEDC7C4592CCB7E, 0xE95A17CFCF63D4AC, 0xC5A8F05F0C78F770, 0x386981FAC3E25272, 0xDD7CD0B4AB9A79D3, 0xD9455DDAD31D0592, 0x994588049EBE35C8, 0x7820458445B7DF6, 0x160C1A4D5730403C, 0xD554560F2A51E183, 0x27B420420DC7},
{0xED6F9F18F5F91D9B, 0xD0140983A4C9F4FA, 0x4B28E37741FCEC6E, 0x58485D7E32AF47F7, 0xBFCAD3B8EF182455, 0xAA683462489724D5, 0x4F7F01FFFD1C1E61, 0xDB4F6A13AEBB1ACA, 0x40272AE951D7AD1B, 0x430F04D3C2402C98, 0x67C05BFAD21BAAF1, 0x53D2C0CD2C47},
{0xBA47E3D71B355EF5, 0xEDE1D03F79CAC2E3, 0xF12082CA2D8570E2, 0x33DB874355B82195, 0xAED62CBE488111EF, 0x8FF5A83E933036A1, 0x5FC5432547B62106, 0x3675123E1B5D6362, 0x187E4E847EDF9ACC, 0x92E55D9773F0AB6E, 0x2FB79EE22F3B6FA7, 0x59F9721DDC1B}};
static const uint64_t table_v_qr[TABLE_V_LEN][NWORDS64_FIELD] = {
{0xCCCCCCCCCCCD41EF, 0xCCCCCCCCCCCCCCCC, 0xCCCCCCCCCCCCCCCC, 0xCCCCCCCCCCCCCCCC, 0xCCCCCCCCCCCCCCCC, 0x467CCCCCCCCCCCCC, 0x5CCF962F575DF8B, 0x3953C2CA47D95926, 0xC50BC81A120A6C9F, 0xDE486C73B57C04C7, 0x3C38F0BBEDB4E68A, 0x35D48FD9C405},
{0x6666666666657C21, 0x6666666666666666, 0x6666666666666666, 0x6666666666666666, 0x6666666666666666, 0x61B6666666666666, 0xD852A3BF5F0CB992, 0x67EE158584451A2A, 0x7E370833B2D70F38, 0xC8D1DC1CF1BA4DB8, 0x95A0AF27BC510F50, 0x43CB58E6F11},
{0xB891DB891DB8926D, 0xDB891DB891DB891D, 0x1DB891DB891DB891, 0x91DB891DB891DB89, 0x891DB891DB891DB8, 0xB7A1DB891DB891DB, 0x7667EA3E359A528F, 0x920F68111BC2395B, 0x73153DF2CE971E2C, 0x16EDA0D863AC7DA5, 0xBF837289A3FC18BF, 0x5ADF5C37BA11},
{0xEDC48EDC48EDB246, 0x8EDC48EDC48EDC48, 0x48EDC48EDC48EDC4, 0xC48EDC48EDC48EDC, 0xDC48EDC48EDC48ED, 0x49A48EDC48EDC48E, 0x590A01C2CFF1EF31, 0xF144BE828EE398A4, 0x7553BC320111D67F, 0xAE524764F48D28A2, 0x7D745F00E9774A86, 0x16C21BBD6A1},
{0x5E40E05A0E84063C, 0x1F4D776F0A51A9CB, 0xCB5E40E05A0E8406, 0x61F4D776F0A51A9, 0xA9CB5E40E05A0E84, 0x72C61F4D776F0A51, 0x618B216FB9C76A1E, 0xE22409F266B16463, 0x894A7D245553FD6B, 0x4E89F364CCE00FA7, 0x77A8C743F3083EC9, 0x188BE18D4AC5},
{0x7DC0E6ABEADE3F10, 0x323668C519083ECD, 0xCD7DC0E6ABEADE47, 0x47323668C519083E, 0x3ECD7DC0E6ABEADE, 0xA347323668C51908, 0xCFA800E85F71B1FE, 0xF36E5745D988B7A, 0xE7F654456F1F4116, 0x3F5EDBEC2C210D61, 0x39B0FEDD215C1DCA, 0x1705E4626A37},
{0x791C39AD37694088, 0x40791C39AD376940, 0x6940791C39AD3769, 0x376940791C39AD37, 0xAD376940791C39AD, 0x6C2D376940791C39, 0x4A463885B9946D81, 0x736B37A93397FE42, 0x3874F55B29BB4D54, 0x5F7A8A5F8D7543C5, 0x228CCBA8F76BD619, 0x5096624D7492},
{0xA331EBB0C9B54BA9, 0x51A331EBB0C9B551, 0xB551A331EBB0C9B5, 0xC9B551A331EBB0C9, 0xB0C9B551A331EBB0, 0xC980C9B551A331EB, 0xC7BC1BC679178B4E, 0x7072B575C98A5F98, 0xB10657E6A1B9DEA2, 0x71773BA18E92437A, 0xAD4025945D8B2AB8, 0x2F2C83A4E8D6},
{0x732233773223377C, 0x3773223377322337, 0x2337732233773223, 0x3223377322337732, 0x7732233773223377, 0xC637322337732233, 0x2695C5C06B69B3F6, 0x2330B3C47A0D9F3, 0x1FF319B45BEC27C0, 0xA128906C609EE6B9, 0x736A7518122E449F, 0x1FCE86244E63},
{0x6EE64466EE6441DB, 0x466EE64466EE6446, 0x64466EE64466EE64, 0xEE64466EE64466EE, 0x66EE64466EE64466, 0x63D6EE64466EE644, 0xA64EE10DFC0F7507, 0x7E19CCA11263939B, 0x39CF2CD41A04B92C, 0xB2FBF371165340D9, 0x53745B07D6DF8B00, 0x44F4C0618554},
{0x70E5437D550C15E9, 0x514AB52CDC183AC2, 0xA4D63DFA7AA6594A, 0x46DAD39BC3F3F19, 0x82FD5B4A38522B72, 0xAD58A5AA7E8D2ECF, 0x523BAAB70A135BE2, 0x45782546050175F7, 0xB24F33FAA2472B55, 0xEBA7A14C1F8593CD, 0x20600FBAB2D24E65, 0x133D309F7EC7},
{0x8EEB4AB02E5A2272, 0x8EB9599CB8AAD0F4, 0xB06CC77E62BB7EF8, 0x32986176DFFA11C5, 0x1BAC3B085C0081D9, 0x69272A1BEAA860AF, 0xE41E6EBFB6ED0D08, 0xF255608B042DB67E, 0x1279C6C0D0C40109, 0x76B7BA4E30FA03B6, 0xD3DDD4F6F5A7EB7, 0x106A8E48CD0F},
{0xD5120148FEAF2C06, 0x255365F9DAA4C4B8, 0xCC272EFC74777061, 0xD9E68887C98D5C50, 0x383B3424E91729B, 0xE0B5120148FEAF2C, 0x1BE4FA2B9F7CFD78, 0xDA98A1C587680DD9, 0xACC09E7217DDD41D, 0xBAB5E239D699C58C, 0x41FD047089438309, 0x858395E2C66},
{0x94FAC8FF3E686241, 0xB72999CF503E0946, 0x2F59559E717C42A, 0x412EFA3785EBB9F, 0xAD808B51BA81A8AC, 0x4BE4FAC8FF3E6864, 0x8C1AAEA7B9495845, 0x94D196357B071596, 0x4FBF87DA63CFBC99, 0x666394A603DFBB5D, 0xAA328976810C7C69, 0x6AA898DF5E6A},
{0x40E70907368FAAA3, 0x2531EC3903CE9F2C, 0xF8AB9BFACF708D95, 0xD2DE3A9B1838859A, 0x4E47B12D7C682948, 0x281BDC83C4953F02, 0xDE0EF99ABED7AFEA, 0xB81783A3E8034AE6, 0x3E73219AAC32B265, 0xA6F25C569E80F4D3, 0x6961E44D2E61E550, 0x54AF9D7748CE},
{0x4EF61479F650B3CA, 0xE4161CB8F931D792, 0xAD6C0EDA1D651114, 0x96969F3A055F9963, 0xA55811F1BE797DD9, 0xBB36DA0672F2CEF4, 0xBCD0F6F9FFB265C5, 0x868F4BABA3739212, 0xDA96099F90F8EC8D, 0xF6B719FF6C14091F, 0xEF5131B07D9BA208, 0x15F75A78FB86},
{0xB5CA528D6B5CA529, 0xCA528D6B5CA528D6, 0x528D6B5CA528D6B5, 0x8D6B5CA528D6B5CA, 0x6B5CA528D6B5CA52, 0xB27528D6B5CA528D, 0xD7C00A95FC590145, 0x4E4610B31250410D, 0x92EB9C10C371F0FC, 0x71D124AD03784C6D, 0xFBA87309E1A6D857, 0x2DF3B0F268CD},
{0x6B5AE52946B5AD2D, 0x5AE52946B5AE5294, 0xE52946B5AE52946B, 0x2946B5AE52946B5A, 0x46B5AE52946B5AE5, 0xD0BE52946B5AE529, 0x5BEAE3E345C8E7D7, 0x9D2D7059D4BB6A4E, 0x18F7C0F408EA159, 0x4E11D89176651539, 0x48671FC6C152F99C, 0x530CE08D1028},
{0xCE57AA6B0A6E427F, 0x9B8F883433A0EB6A, 0xBD90869A824E3109, 0xD1840719519276EA, 0xF601CD0A72F12455, 0x8904C6A15653D646, 0x72DB02908565884, 0x71294DC40DC2EB13, 0x361608701CEA745E, 0x1279CC6C51A4F800, 0xDD923715582E9EDE, 0x6578E5CC44C5},
{0xB218A10D98E7AC3C, 0x3CAF3BDD50AC19A5, 0x2A2B48E62A13DFAE, 0xA9CE07E98542FDD0, 0x4B70FD8D0D9C06C5, 0x6829379D7BC99C61, 0x57C3D248CC251489, 0x9F1367A307C698E9, 0x2CC0B2B8746361EF, 0x9A6A53D6400CB8EA, 0x7888C0894B30195B, 0x29E026757F97},
{0xB7B49E77DD01B05A, 0xC7FCDE689EA7A30E, 0x3B83E48534D253E7, 0xE1F4F28B24C70D5F, 0xC226AF798CDAE97, 0x29592FFABA44E0BF, 0x451BFFACF7902A0B, 0xEF0C4136DB713262, 0x7F066B8D7CD90C93, 0x193C99BB6A2BD9E4, 0xDCCEB7DD7547E7EE, 0x1BC6242C97DB},
{0xE49911F2B13CA178, 0xF8D4BCF08B36207D, 0x2605805106CF5C4D, 0xBB2BF392469C496A, 0xC6EE51B30BE997A4, 0x3636AEDEA9BE252F, 0x5962BFE5CE1E434D, 0x80A1219F24FBAA71, 0x9727D3F901B9FA59, 0x9C7DB47FBDB8D837, 0x260B21A1EA96DA92, 0x58C7EC9D75A5},
{0x11372FCC7943203A, 0x5C4549B345DE13E1, 0xB35E08AA984D8EEB, 0x9AD22A4F3D9CF45D, 0x84408FBE68108C13, 0xD6F34279BA1D5079, 0xFD86BCE1D485CE9C, 0x7547DCC9E6A72B9A, 0x82BAC6E5640D1B8, 0xA0AA9060525B5FA0, 0x9DF6B6008023369A, 0x64534002FC0F},
{0x338AA1050E3B47F2, 0xA779AFC5AA01E0AA, 0x7A24EAE40DA1607F, 0x2F3BC85F75845B2F, 0xB63ECCFACC4A42BC, 0xB970439A64648442, 0xFC7FE81D54BCBFAD, 0x8F070C333697311A, 0xC3F49A6F3F169CEA, 0x5D4853A9EA5F7ED, 0xD518DE0B200B8454, 0x527415AF5FE1},
{0x29D6C703462657AD, 0xDC60DB370D32F7B9, 0x7ECF292BC2C418DD, 0x37B10E0D29478FC0, 0x2DFAFEF9EA3B8E16, 0xE9716B45FA8908A4, 0x6CB32B342A6375FF, 0xFD73F31AB04928C5, 0xB397940272F73C0C, 0x5B001264620355C2, 0x5803F26169F9945B, 0x5C5620099D9B},
{0xDA0656B84FE5EB1E, 0xBA4CBC548666840D, 0x1A44273AF862539E, 0x1FFD96A7C772BACB, 0x953D86F6FED07774, 0x7BBC68E6D3E03A59, 0xA78131504FEA94B4, 0x5FF580356C9EF9E7, 0xDF4576DB17102D3C, 0xCA73668DEBAABC08, 0xC73232385D81A0CB, 0x14DC1275B692},
{0xE1C98F3C564A49CD, 0x76847854DFFF1979, 0x6DD3A9A2B019D474, 0xFEB9A85944A3C836, 0x4C554E80A25DEBB9, 0xC247DBF7209CBA59, 0xE606E4DA4D403E68, 0x5AABAE35231E6C78, 0x1E08F32D70B4CF5A, 0x8EDD7B4A0D3949FA, 0xA549CBAE571FABD6, 0x345B562BB1C2},
{0x3DDA63D9B718EF13, 0xDB18FF110367AB22, 0xB7A690D61E54A79F, 0xD1FB6E7474B2F230, 0x5D6F299A0CDCA8B4, 0xBDB8418CAF5F5E57, 0x87950067C9C186CF, 0xF190BC388A72A53B, 0x213C2BED23C24CA9, 0xD23020B606F4B8B5, 0xE7CFBF2E0DE63E1D, 0x85488821CA3},
{0x2E87222F0886018B, 0x2006A348352327DC, 0x19561FC0617F066, 0x390FD49917EAD64, 0xC8962E05BE5C859E, 0x9098F7D823688E17, 0xA367361FE7730947, 0x4C6AE2F141441363, 0x6012B07C3CA41E86, 0xB27005C079FEB1B6, 0x825B9BFC26C91F27, 0x3F1183F8513F},
{0xB584B99EC62D9D35, 0xA4912F9464B54407, 0x74A10C6ED11079EF, 0x42C935F4B27768B1, 0x355CC43459FC8F5, 0x83FB4BDA9E4C1B5, 0x362D54FAF7050831, 0xED24CAC0D587AF78, 0x520C08B595DEF623, 0x9C385DB3FD4B1742, 0x12B09C148B913905, 0x4C96EA957BF4},
{0xCCB2CE7886EF239D, 0x47C704F6F492B661, 0x63CDC17F473B3143, 0xE43575F9DEDACC50, 0xED36745A83436E23, 0xB43E3A2A47D36381, 0x6FE523A476BF9F48, 0x82B1F402B3BD2A0, 0xDBE6E728B539ADAE, 0xA37C34807A76FF4E, 0x538EE747772483FB, 0xDB5A5E658A6},
{0xEFAD9377610BEA32, 0xECEDC7C4592CCB7E, 0xE95A17CFCF63D4AC, 0xC5A8F05F0C78F770, 0x386981FAC3E25272, 0xDD7CD0B4AB9A79D3, 0xD9455DDAD31D0592, 0x994588049EBE35C8, 0x7820458445B7DF6, 0x160C1A4D5730403C, 0xD554560F2A51E183, 0x27B420420DC7},
{0xED6F9F18F5F91D9B, 0xD0140983A4C9F4FA, 0x4B28E37741FCEC6E, 0x58485D7E32AF47F7, 0xBFCAD3B8EF182455, 0xAA683462489724D5, 0x4F7F01FFFD1C1E61, 0xDB4F6A13AEBB1ACA, 0x40272AE951D7AD1B, 0x430F04D3C2402C98, 0x67C05BFAD21BAAF1, 0x53D2C0CD2C47},
{0xBA47E3D71B355EF5, 0xEDE1D03F79CAC2E3, 0xF12082CA2D8570E2, 0x33DB874355B82195, 0xAED62CBE488111EF, 0x8FF5A83E933036A1, 0x5FC5432547B62106, 0x3675123E1B5D6362, 0x187E4E847EDF9ACC, 0x92E55D9773F0AB6E, 0x2FB79EE22F3B6FA7, 0x59F9721DDC1B}
};
static const uint64_t table_v_qnr[TABLE_V_LEN][NWORDS64_FIELD] =
{{0xE85E85E85E85F161, 0x5E85E85E85E85E85, 0x85E85E85E85E85E8, 0xE85E85E85E85E85E, 0x5E85E85E85E85E85, 0x65385E85E85E85E8, 0x85F916A5F6E08638, 0x2609C462575E3A01, 0xD55BC460BFFDB5F7, 0x394FD56C08877041, 0x90A4C64E64B48269, 0x155B182E978E},
{0xBD0BD0BD0BD074F6, 0xBD0BD0BD0BD0BD0, 0xD0BD0BD0BD0BD0BD, 0xBD0BD0BD0BD0BD0B, 0xBD0BD0BD0BD0BD0, 0xB39D0BD0BD0BD0BD, 0x981077DADCECBF8E, 0x84DD13216CFDC8E1, 0x65BF0DC9ADEA2134, 0x4046BEA875292C81, 0x96FEEECC09D1A583, 0x34F2E90F31C3},
{0x94DFB461AC813046, 0x794DFB461AC812E7, 0xE794DFB461AC812E, 0x2E794DFB461AC812, 0x12E794DFB461AC81, 0x3D0E794DFB461AC8, 0x70595ED790F5300A, 0x8AC21DF01D745314, 0x960E4F84DA8D1645, 0x5B7E64183952E46B, 0xF22C180908C76B1F, 0x4768EB30E5C6},
{0x88455121DEEA9B08, 0x788455121DEEABB7, 0xB788455121DEEABB, 0xBB788455121DEEAB, 0xABB788455121DEEA, 0xE53B788455121DEE, 0xC8CE631746684732, 0x7D5D2A56DD6FBE22, 0xD6AD8D86B52354AE, 0xD1BD7280508807CF, 0xA1C516D87EBCCC99, 0x396575A76D53},
{0xD62298ECA7759C89, 0x4D62298ECA7759C4, 0xC4D62298ECA7759C, 0x9C4D62298ECA7759, 0x59C4D62298ECA775, 0x796C4D62298ECA77, 0xAE6DBC543FEF825C, 0xEC1F7E95B33ED029, 0xCA719FAF0D52EACA, 0xF0376BE32D0BF058, 0xF65BA4732A06CB30, 0x253E29FDA895},
{0x2D3E21C74B076D2D, 0xE2D3E21C74B0778E, 0x8E2D3E21C74B0778, 0x78E2D3E21C74B077, 0x778E2D3E21C74B07, 0x2288E2D3E21C74B0, 0x114736656CB88D28, 0x65C8937E512FEBC1, 0x306EEB4AB789442, 0xF0BAF2EB5B82DA71, 0xD1557C1ADE14F33F, 0x281EF5D67B92},
{0x55A7CC22BD034BC5, 0xCF664D2B55543DB8, 0xAD0509637903BB29, 0xCC764B6DB31CC125, 0xA38DE755C3A64634, 0xC5DBC1418728812C, 0x54CDBEA5DAAB0EBF, 0x784DA3FDEE94F653, 0xACD92FABB346E2C0, 0x309E575438F3301C, 0xDE6DA98747E3BC84, 0x78998A0688},
{0x14E884DC556CCE17, 0xF813B625562FC7FD, 0xD410AA497515C755, 0x4395124C11891A90, 0x392344FF261926C0, 0x5B0104CE685B1520, 0xA32FA4F27454F2D6, 0xDDED7CB7AF975B5C, 0xFEA15A43C78AC218, 0x89AE7B37DEB4C0E0, 0x48661EEF6DCF9520, 0x11ADE16CDC2E},
{0xD2261143E5B763C9, 0x7BAF0692270E1A07, 0x3E5B763C797E0B76, 0x2270E1A07D226114, 0xC797E0B767BAF069, 0x8FA2261143E5B763, 0x6F563606E110ED58, 0xCD1C300154910AA4, 0xB61EDFD60C5C6096, 0x12CADF965191532E, 0xA045CA5ADE8C8CA6, 0x2CDC07A09F1D},
{0x952C939D91AFBD6C, 0xDB189B941022B733, 0xD91AFBF752331AB4, 0x41022B733952C939, 0x752331AB4DB189B9, 0x91552C939D91AFBF, 0x6376CA8518BA8EA, 0x4C144651E91CACE2, 0xE0E13E3F7AF8AC34, 0x4C7E7CDE3D51F816, 0x11E5E216628DA39F, 0x3C9C0D30F762},
{0xC605DAAC2686111, 0x653B01B6DAB28C3B, 0xC50A3A32DE5449A4, 0xB6EBC1C42E96427E, 0x8FEFFAE8A88084D9, 0x58EA39884624C641, 0x9EC005ED22C5BC45, 0x1633B0FBD77D6D9D, 0xA57C267B6FBA36DB, 0xF94465FAC0B899A2, 0x34A4BE281ED17637, 0x55D1BDD26591},
{0xC709286502B5CCB, 0xFDA560011E994595, 0x4856E21B8EEF3C44, 0xE6FF4B98A9EA2DE2, 0x9887CBBDFB34929F, 0x7E47E75497B06B9B, 0xE723E79ABA5D9470, 0x2C05C07824B8E6E, 0x5E4E45149E3C5445, 0x2452AE29E3055EA4, 0xEF90DE3635F81ED5, 0x2811146405A3},
{0x9807214A3A1C1CF3, 0x7A0E708928E1F773, 0x6B79A82BEC4DCC5F, 0xE98AFBE2931E7695, 0xF1BFAF7F0D6FE513, 0x729355B40CC74834, 0x7355193ADF5FC317, 0xAABE07A1788CB696, 0x22D720814DB72B6B, 0x37DF09E734DE45BA, 0xFD056FDA4F240CBA, 0x68ABBB7B5C8E},
{0xC3777B85DA951B35, 0x729E2EE622CB06CE, 0x142662CA9F3EC02B, 0x79B13BB964738D59, 0xD0D82AA614F52FF, 0x2073598189B312EF, 0x187D2FB5FF497E99, 0x55FEA80CEF2A4B0E, 0x6B197F79D5FAF833, 0x254447C18292F844, 0x60F938B568EE1543, 0x71826A2ADCA},
{0x9C02260C68B4DBCD, 0xEAD5B56BFB777BE, 0x3BC3BE5177278FD6, 0xDAB6622B90CD39DE, 0x90CC3EC6ACA6DDD0, 0x6E158FF767CE5D2C, 0xA8B669D3FF7489EA, 0xAF133837592C7ADA, 0xFBF80D62062EC026, 0xC3512D9A00005FBB, 0xB759F49E11D399A6, 0x2B5BC9341B5D},
{0xC32617FB97A7BA46, 0xDC97C62323C3A3A3, 0x100C4C10F8AD3EB2, 0x303659A310A3583D, 0x12DA436E2F3F2E72, 0x4D50F367A011A161, 0x8328C3F9F44A3084, 0xF982C9DA22658656, 0x5EB7238A18DD90A7, 0xB9156E1D1B343898, 0x57243EC083BFEF2F, 0x3DE52126EF4},
{0xBBD06880C51C680B, 0x7A81A7C7078464C3, 0xFDECD7041B4ECF3E, 0x2C5C3D04ED2F2A03, 0x5D174A6A4E7F7DB4, 0x1B52D2539D1EA2E8, 0xA5CC20018839AB95, 0x67625D02AE4CF980, 0x186074DCBD384821, 0x9E5E42872A3C7A83, 0x545832703A5A56B9, 0x27681CF8D9FB},
{0xD629BC89002BCCEA, 0xB88D005E2C3A8F32, 0x56386D851D5B66D8, 0x60ED69D4ABC2EE09, 0x1731219EC24A5538, 0x966D87BCF622EA5D, 0x62A6B07E4C8B3CEF, 0x6EA16F4B509B81A3, 0x7A97D35B5CDE162D, 0xE25FB4ACF2AF1E4F, 0xC48E64140BD3474E, 0x21FDD6C8FB82},
{0x9288477180A6C951, 0xB2D2DE965A033D61, 0x3BA1694AB827311A, 0x70A5B57FC1C70CDC, 0xBFD11385625A2E5B, 0x2DDDAFB04A38853F, 0xF21823FF1B225FDC, 0x5F007A2E1641AEB8, 0xC3E5684AC220ECAA, 0x78179AF27DD10F63, 0x96DC98F67C36644F, 0x7D6D89BB770},
{0x829327C9D19D0226, 0xD65D25DC7C2E4992, 0xD5DBE128D0A23BA2, 0xF6DFC62FD21334A4, 0x651EAEB5C3A9A583, 0x180C253598055EB9, 0x3F73FA2EEF9168FA, 0x4318BBEE307725D0, 0x54DD26A9FC5450F7, 0x76ABA5758680DBA0, 0x353ED351A6A5F735, 0x2FF3A6573DE4},
{0xB9993936AA2301F8, 0x7B319EACE5E9B127, 0x12E616BD697BA4E, 0x811B1F35F96913B0, 0x474DB18B6AB00C82, 0xC1FFF493FE2C0901, 0x796424D7A11AEDE9, 0x61076638D85C4C48, 0x64774660A3BE93D0, 0x43FA3F433B9D067D, 0x47A0B426F92F7600, 0xA280AE8D170},
{0x3581912DE993F071, 0x70141CFFC8A2ECAF, 0xC3EB4B7D9EAADF4D, 0x39E0D5685C6769F8, 0x44208A1289B360A9, 0x1495F58B3248D82B, 0xCBC66BB98CDA2E99, 0xCC3F8763F217FA81, 0x495812161E7D7E11, 0x255FA1A2A5D70135, 0x240F5A6F7EAE5BA4, 0x4C1F4DD638F5},
{0x5B9845DD9A79003D, 0xEF65F03C8F56ECBD, 0x30F64FF52B455D62, 0xD45579863FAD5D92, 0xC798CD9C72EB564D, 0xDD15C4F63ED0D645, 0x9F35EC5BCF419520, 0x2759D2CB3306DFB3, 0x6A4CEE0C84723002, 0x62AE428E1405808C, 0xA93787CE06A12315, 0x4885205A0A7F},
{0x3184F5FF10FC6AF3, 0x143B921A36E08BDC, 0x4DA6A729B2406BF7, 0xE6678BF19EEF357A, 0x96091214F1C2F4A2, 0x9F07E61747E02986, 0x48FA86D281046604, 0xFF69050DD5E29481, 0xF97F744AB920445E, 0x16B828177FE35D68, 0x2A44107C12A0C668, 0x65CD488721CA},
{0x4E5420F1827B439D, 0xF487A4ED360B1C4D, 0xC55EFC7F8D8112D0, 0xED67A91DBC5910C6, 0x9E9A78EFA44FC34F, 0xD40F65D4211D8623, 0x5C21F3F0FE48DBC9, 0x9CEA4A83954032F, 0x68A443A160CCF02, 0xBA2D35302646DABE, 0xB27CC0AAD03BA372, 0x2E3F49905A08},
{0x40785DE28D4C9530, 0xA6405C1C01E10071, 0x3C209F250C73B2C8, 0xBF22E6EBADC20A64, 0xD1DDAB04AF2AB602, 0xA33C04772868D58C, 0x98DA3CE309D547DA, 0x4DD504F6F173D486, 0x283B355D938C1316, 0x99001A20441BA13A, 0xE8C99EC8D3BB4B46, 0x6F688BD1C61},
{0x459A64577F98DD28, 0x3FD6890B60AA7022, 0x32B84AB229B33D20, 0x7CA6E1524F6EBF03, 0x4F0242DD469A4D8B, 0x53EAA4C1EBC77C19, 0x62C19F1C435AC30D, 0xF230AE4E1F1BF94B, 0xCF7E083E29C16D7E, 0xCA42C2833B78234E, 0xD01EFFD11DB566A8, 0x224E1F2FFD2E},
{0x6EDAA71406539762, 0xB74F189440621EB1, 0x345F3262EC4F13E0, 0x23185407A289E9FD, 0xD105FEB3ED85CEC2, 0x11F70813D04E49FC, 0xD99654FECB39AB46, 0x734ECF9475139205, 0x54E95C9BD579AED5, 0xE044D2C9270C1251, 0xE60CAFCEA4BB3508, 0x552B57BCA931},
{0xD91B6C9B924D91B6, 0x9B924D91B6C9B924, 0x91B6C9B924D91B6C, 0xB924D91B6C9B924D, 0x1B6C9B924D91B6C9, 0x312D91B6C9B924D9, 0x17D193651E9DCA60, 0x8DF224D4272EC01E, 0xCBD2BC92A7A778F6, 0xA59CF2B6356CD90E, 0x9C712EB8F35468FD, 0x5C2C61931F7C},
{0x249B236D93724969, 0x6D937249B236D937, 0x49B236D937249B23, 0xD937249B236D9372, 0x9B236D937249B236, 0x7D4249B236D93724, 0x6F78BF6586101FB3, 0xDEBA77A01FF372B9, 0x2809BF0C10D132CA, 0x15E12E137474B550, 0x32E144163D1A7A6C, 0x83BCB784FD},
{0xA014E250439995F, 0x45FC65F1FFF85333, 0x6BCB9B2F717EC6B4, 0xE17F29C4A3AAB256, 0x84007F11103DBAF3, 0x8F00A6A9F3A093F6, 0x9726358A43891D51, 0x897A6562E06B392, 0x9C43741CF4F314B9, 0xF134466DE6EFE2AB, 0xF564982D2C7FD077, 0x1314C36F69C9},
{0xA43641B1D7CEDC7D, 0xF0874E7045509B0D, 0x792E7B86FF0D73E7, 0x7B8EC819E2656382, 0xDB846DE5527F9573, 0xCBAED11FBDC7B5A7, 0x9CF8B6F734116414, 0xAB4016ED22D2B78C, 0x901482B46AAC884D, 0x6F313D2D60B58E49, 0x8226CE453AFF56F5, 0x541B0694E059},
{0xE39251FB5F896DD7, 0x861156ADC66BF25B, 0xD3B6E410C9EB77F6, 0x149A5B2E22C5FF6, 0x39BF19B234BC83FE, 0x6FC6DDCDE9500C15, 0x33D635192E7CA410, 0xF40BB7C04811EFE5, 0xB95BDBAD0678F5E3, 0xFFEE8DDD2907E2DA, 0x71BB095C5885E70A, 0x3006B1C7034E},
{0xD681EED8B087DAC7, 0x90726086FB0A1D9F, 0x643AD6038FE15FF2, 0xF6524CCDFEB45CE0, 0x511BD3AA0B479432, 0xFDAA3B25B585A917, 0x16C0CA87EB477009, 0x5DCAD9871ABB0038, 0x5BA46393DEEC08B5, 0x9AC8A0B793849197, 0xA8F7FEDA5FA4EA5A, 0x3A742CC9DEB9}};
static const uint64_t table_v_qnr[TABLE_V_LEN][NWORDS64_FIELD] = {
{0xE85E85E85E85F161, 0x5E85E85E85E85E85, 0x85E85E85E85E85E8, 0xE85E85E85E85E85E, 0x5E85E85E85E85E85, 0x65385E85E85E85E8, 0x85F916A5F6E08638, 0x2609C462575E3A01, 0xD55BC460BFFDB5F7, 0x394FD56C08877041, 0x90A4C64E64B48269, 0x155B182E978E},
{0xBD0BD0BD0BD074F6, 0xBD0BD0BD0BD0BD0, 0xD0BD0BD0BD0BD0BD, 0xBD0BD0BD0BD0BD0B, 0xBD0BD0BD0BD0BD0, 0xB39D0BD0BD0BD0BD, 0x981077DADCECBF8E, 0x84DD13216CFDC8E1, 0x65BF0DC9ADEA2134, 0x4046BEA875292C81, 0x96FEEECC09D1A583, 0x34F2E90F31C3},
{0x94DFB461AC813046, 0x794DFB461AC812E7, 0xE794DFB461AC812E, 0x2E794DFB461AC812, 0x12E794DFB461AC81, 0x3D0E794DFB461AC8, 0x70595ED790F5300A, 0x8AC21DF01D745314, 0x960E4F84DA8D1645, 0x5B7E64183952E46B, 0xF22C180908C76B1F, 0x4768EB30E5C6},
{0x88455121DEEA9B08, 0x788455121DEEABB7, 0xB788455121DEEABB, 0xBB788455121DEEAB, 0xABB788455121DEEA, 0xE53B788455121DEE, 0xC8CE631746684732, 0x7D5D2A56DD6FBE22, 0xD6AD8D86B52354AE, 0xD1BD7280508807CF, 0xA1C516D87EBCCC99, 0x396575A76D53},
{0xD62298ECA7759C89, 0x4D62298ECA7759C4, 0xC4D62298ECA7759C, 0x9C4D62298ECA7759, 0x59C4D62298ECA775, 0x796C4D62298ECA77, 0xAE6DBC543FEF825C, 0xEC1F7E95B33ED029, 0xCA719FAF0D52EACA, 0xF0376BE32D0BF058, 0xF65BA4732A06CB30, 0x253E29FDA895},
{0x2D3E21C74B076D2D, 0xE2D3E21C74B0778E, 0x8E2D3E21C74B0778, 0x78E2D3E21C74B077, 0x778E2D3E21C74B07, 0x2288E2D3E21C74B0, 0x114736656CB88D28, 0x65C8937E512FEBC1, 0x306EEB4AB789442, 0xF0BAF2EB5B82DA71, 0xD1557C1ADE14F33F, 0x281EF5D67B92},
{0x55A7CC22BD034BC5, 0xCF664D2B55543DB8, 0xAD0509637903BB29, 0xCC764B6DB31CC125, 0xA38DE755C3A64634, 0xC5DBC1418728812C, 0x54CDBEA5DAAB0EBF, 0x784DA3FDEE94F653, 0xACD92FABB346E2C0, 0x309E575438F3301C, 0xDE6DA98747E3BC84, 0x78998A0688},
{0x14E884DC556CCE17, 0xF813B625562FC7FD, 0xD410AA497515C755, 0x4395124C11891A90, 0x392344FF261926C0, 0x5B0104CE685B1520, 0xA32FA4F27454F2D6, 0xDDED7CB7AF975B5C, 0xFEA15A43C78AC218, 0x89AE7B37DEB4C0E0, 0x48661EEF6DCF9520, 0x11ADE16CDC2E},
{0xD2261143E5B763C9, 0x7BAF0692270E1A07, 0x3E5B763C797E0B76, 0x2270E1A07D226114, 0xC797E0B767BAF069, 0x8FA2261143E5B763, 0x6F563606E110ED58, 0xCD1C300154910AA4, 0xB61EDFD60C5C6096, 0x12CADF965191532E, 0xA045CA5ADE8C8CA6, 0x2CDC07A09F1D},
{0x952C939D91AFBD6C, 0xDB189B941022B733, 0xD91AFBF752331AB4, 0x41022B733952C939, 0x752331AB4DB189B9, 0x91552C939D91AFBF, 0x6376CA8518BA8EA, 0x4C144651E91CACE2, 0xE0E13E3F7AF8AC34, 0x4C7E7CDE3D51F816, 0x11E5E216628DA39F, 0x3C9C0D30F762},
{0xC605DAAC2686111, 0x653B01B6DAB28C3B, 0xC50A3A32DE5449A4, 0xB6EBC1C42E96427E, 0x8FEFFAE8A88084D9, 0x58EA39884624C641, 0x9EC005ED22C5BC45, 0x1633B0FBD77D6D9D, 0xA57C267B6FBA36DB, 0xF94465FAC0B899A2, 0x34A4BE281ED17637, 0x55D1BDD26591},
{0xC709286502B5CCB, 0xFDA560011E994595, 0x4856E21B8EEF3C44, 0xE6FF4B98A9EA2DE2, 0x9887CBBDFB34929F, 0x7E47E75497B06B9B, 0xE723E79ABA5D9470, 0x2C05C07824B8E6E, 0x5E4E45149E3C5445, 0x2452AE29E3055EA4, 0xEF90DE3635F81ED5, 0x2811146405A3},
{0x9807214A3A1C1CF3, 0x7A0E708928E1F773, 0x6B79A82BEC4DCC5F, 0xE98AFBE2931E7695, 0xF1BFAF7F0D6FE513, 0x729355B40CC74834, 0x7355193ADF5FC317, 0xAABE07A1788CB696, 0x22D720814DB72B6B, 0x37DF09E734DE45BA, 0xFD056FDA4F240CBA, 0x68ABBB7B5C8E},
{0xC3777B85DA951B35, 0x729E2EE622CB06CE, 0x142662CA9F3EC02B, 0x79B13BB964738D59, 0xD0D82AA614F52FF, 0x2073598189B312EF, 0x187D2FB5FF497E99, 0x55FEA80CEF2A4B0E, 0x6B197F79D5FAF833, 0x254447C18292F844, 0x60F938B568EE1543, 0x71826A2ADCA},
{0x9C02260C68B4DBCD, 0xEAD5B56BFB777BE, 0x3BC3BE5177278FD6, 0xDAB6622B90CD39DE, 0x90CC3EC6ACA6DDD0, 0x6E158FF767CE5D2C, 0xA8B669D3FF7489EA, 0xAF133837592C7ADA, 0xFBF80D62062EC026, 0xC3512D9A00005FBB, 0xB759F49E11D399A6, 0x2B5BC9341B5D},
{0xC32617FB97A7BA46, 0xDC97C62323C3A3A3, 0x100C4C10F8AD3EB2, 0x303659A310A3583D, 0x12DA436E2F3F2E72, 0x4D50F367A011A161, 0x8328C3F9F44A3084, 0xF982C9DA22658656, 0x5EB7238A18DD90A7, 0xB9156E1D1B343898, 0x57243EC083BFEF2F, 0x3DE52126EF4},
{0xBBD06880C51C680B, 0x7A81A7C7078464C3, 0xFDECD7041B4ECF3E, 0x2C5C3D04ED2F2A03, 0x5D174A6A4E7F7DB4, 0x1B52D2539D1EA2E8, 0xA5CC20018839AB95, 0x67625D02AE4CF980, 0x186074DCBD384821, 0x9E5E42872A3C7A83, 0x545832703A5A56B9, 0x27681CF8D9FB},
{0xD629BC89002BCCEA, 0xB88D005E2C3A8F32, 0x56386D851D5B66D8, 0x60ED69D4ABC2EE09, 0x1731219EC24A5538, 0x966D87BCF622EA5D, 0x62A6B07E4C8B3CEF, 0x6EA16F4B509B81A3, 0x7A97D35B5CDE162D, 0xE25FB4ACF2AF1E4F, 0xC48E64140BD3474E, 0x21FDD6C8FB82},
{0x9288477180A6C951, 0xB2D2DE965A033D61, 0x3BA1694AB827311A, 0x70A5B57FC1C70CDC, 0xBFD11385625A2E5B, 0x2DDDAFB04A38853F, 0xF21823FF1B225FDC, 0x5F007A2E1641AEB8, 0xC3E5684AC220ECAA, 0x78179AF27DD10F63, 0x96DC98F67C36644F, 0x7D6D89BB770},
{0x829327C9D19D0226, 0xD65D25DC7C2E4992, 0xD5DBE128D0A23BA2, 0xF6DFC62FD21334A4, 0x651EAEB5C3A9A583, 0x180C253598055EB9, 0x3F73FA2EEF9168FA, 0x4318BBEE307725D0, 0x54DD26A9FC5450F7, 0x76ABA5758680DBA0, 0x353ED351A6A5F735, 0x2FF3A6573DE4},
{0xB9993936AA2301F8, 0x7B319EACE5E9B127, 0x12E616BD697BA4E, 0x811B1F35F96913B0, 0x474DB18B6AB00C82, 0xC1FFF493FE2C0901, 0x796424D7A11AEDE9, 0x61076638D85C4C48, 0x64774660A3BE93D0, 0x43FA3F433B9D067D, 0x47A0B426F92F7600, 0xA280AE8D170},
{0x3581912DE993F071, 0x70141CFFC8A2ECAF, 0xC3EB4B7D9EAADF4D, 0x39E0D5685C6769F8, 0x44208A1289B360A9, 0x1495F58B3248D82B, 0xCBC66BB98CDA2E99, 0xCC3F8763F217FA81, 0x495812161E7D7E11, 0x255FA1A2A5D70135, 0x240F5A6F7EAE5BA4, 0x4C1F4DD638F5},
{0x5B9845DD9A79003D, 0xEF65F03C8F56ECBD, 0x30F64FF52B455D62, 0xD45579863FAD5D92, 0xC798CD9C72EB564D, 0xDD15C4F63ED0D645, 0x9F35EC5BCF419520, 0x2759D2CB3306DFB3, 0x6A4CEE0C84723002, 0x62AE428E1405808C, 0xA93787CE06A12315, 0x4885205A0A7F},
{0x3184F5FF10FC6AF3, 0x143B921A36E08BDC, 0x4DA6A729B2406BF7, 0xE6678BF19EEF357A, 0x96091214F1C2F4A2, 0x9F07E61747E02986, 0x48FA86D281046604, 0xFF69050DD5E29481, 0xF97F744AB920445E, 0x16B828177FE35D68, 0x2A44107C12A0C668, 0x65CD488721CA},
{0x4E5420F1827B439D, 0xF487A4ED360B1C4D, 0xC55EFC7F8D8112D0, 0xED67A91DBC5910C6, 0x9E9A78EFA44FC34F, 0xD40F65D4211D8623, 0x5C21F3F0FE48DBC9, 0x9CEA4A83954032F, 0x68A443A160CCF02, 0xBA2D35302646DABE, 0xB27CC0AAD03BA372, 0x2E3F49905A08},
{0x40785DE28D4C9530, 0xA6405C1C01E10071, 0x3C209F250C73B2C8, 0xBF22E6EBADC20A64, 0xD1DDAB04AF2AB602, 0xA33C04772868D58C, 0x98DA3CE309D547DA, 0x4DD504F6F173D486, 0x283B355D938C1316, 0x99001A20441BA13A, 0xE8C99EC8D3BB4B46, 0x6F688BD1C61},
{0x459A64577F98DD28, 0x3FD6890B60AA7022, 0x32B84AB229B33D20, 0x7CA6E1524F6EBF03, 0x4F0242DD469A4D8B, 0x53EAA4C1EBC77C19, 0x62C19F1C435AC30D, 0xF230AE4E1F1BF94B, 0xCF7E083E29C16D7E, 0xCA42C2833B78234E, 0xD01EFFD11DB566A8, 0x224E1F2FFD2E},
{0x6EDAA71406539762, 0xB74F189440621EB1, 0x345F3262EC4F13E0, 0x23185407A289E9FD, 0xD105FEB3ED85CEC2, 0x11F70813D04E49FC, 0xD99654FECB39AB46, 0x734ECF9475139205, 0x54E95C9BD579AED5, 0xE044D2C9270C1251, 0xE60CAFCEA4BB3508, 0x552B57BCA931},
{0xD91B6C9B924D91B6, 0x9B924D91B6C9B924, 0x91B6C9B924D91B6C, 0xB924D91B6C9B924D, 0x1B6C9B924D91B6C9, 0x312D91B6C9B924D9, 0x17D193651E9DCA60, 0x8DF224D4272EC01E, 0xCBD2BC92A7A778F6, 0xA59CF2B6356CD90E, 0x9C712EB8F35468FD, 0x5C2C61931F7C},
{0x249B236D93724969, 0x6D937249B236D937, 0x49B236D937249B23, 0xD937249B236D9372, 0x9B236D937249B236, 0x7D4249B236D93724, 0x6F78BF6586101FB3, 0xDEBA77A01FF372B9, 0x2809BF0C10D132CA, 0x15E12E137474B550, 0x32E144163D1A7A6C, 0x83BCB784FD},
{0xA014E250439995F, 0x45FC65F1FFF85333, 0x6BCB9B2F717EC6B4, 0xE17F29C4A3AAB256, 0x84007F11103DBAF3, 0x8F00A6A9F3A093F6, 0x9726358A43891D51, 0x897A6562E06B392, 0x9C43741CF4F314B9, 0xF134466DE6EFE2AB, 0xF564982D2C7FD077, 0x1314C36F69C9},
{0xA43641B1D7CEDC7D, 0xF0874E7045509B0D, 0x792E7B86FF0D73E7, 0x7B8EC819E2656382, 0xDB846DE5527F9573, 0xCBAED11FBDC7B5A7, 0x9CF8B6F734116414, 0xAB4016ED22D2B78C, 0x901482B46AAC884D, 0x6F313D2D60B58E49, 0x8226CE453AFF56F5, 0x541B0694E059},
{0xE39251FB5F896DD7, 0x861156ADC66BF25B, 0xD3B6E410C9EB77F6, 0x149A5B2E22C5FF6, 0x39BF19B234BC83FE, 0x6FC6DDCDE9500C15, 0x33D635192E7CA410, 0xF40BB7C04811EFE5, 0xB95BDBAD0678F5E3, 0xFFEE8DDD2907E2DA, 0x71BB095C5885E70A, 0x3006B1C7034E},
{0xD681EED8B087DAC7, 0x90726086FB0A1D9F, 0x643AD6038FE15FF2, 0xF6524CCDFEB45CE0, 0x511BD3AA0B479432, 0xFDAA3B25B585A917, 0x16C0CA87EB477009, 0x5DCAD9871ABB0038, 0x5BA46393DEEC08B5, 0x9AC8A0B793849197, 0xA8F7FEDA5FA4EA5A, 0x3A742CC9DEB9}
};
static const uint64_t v_3_torsion[20][2 * NWORDS64_FIELD] =
{{0xD89D89D89D8A493E, 0x9D89D89D89D89D89, 0x89D89D89D89D89D8, 0xD89D89D89D89D89D, 0x9D89D89D89D89D89, 0x8B389D89D89D89D8, 0xB4C6B9529F01D8C3, 0x1399AE2626262260, 0xDE85321D9D8185DF, 0x8451DC3FDF91784A, 0xFAEFD5E487381389, 0x6319EE6373CB, 0x3B13B13B13B1248D, 0x13B13B13B13B13B1, 0xB13B13B13B13B13B, 0x3B13B13B13B13B13, 0x13B13B13B13B13B1, 0x7A4B13B13B13B13B, 0xA30792A3BBCAECC7, 0x8E3262972F905537, 0x6EC1E1420B7BAD51, 0x3369C4F4190692FF, 0x9D6D588BD01A282C, 0x28F2E2C80A9},
{0x673D45AA630B09FB, 0x5673D45AA630AE95, 0x95673D45AA630AE9, 0xE95673D45AA630AE, 0xAE95673D45AA630A, 0xD4595673D45AA630, 0x6D7B45385F91ACC, 0x7FDE0F3B044702EF, 0xF1BFC4766FC2E18A, 0xD67138B8790E3167, 0x9EF75C6F0552A406, 0x2C5A25459904, 0xF6C4681424EE5801, 0xAF6C4681424EE5FA, 0xFAF6C4681424EE5F, 0x5FAF6C4681424EE5, 0xE5FAF6C4681424EE, 0x7FAFAF6C4681424E, 0x71E7F021FC96E1CF, 0xBD317223E4665091, 0x4D1B06EED834E4E, 0xF423F47B02EEF4B8, 0xA418B4D55C23C88, 0x94F95559E31},
{0xBC8EA75EFC1DB814, 0xDC562840F895B742, 0xEA75EFC1DA922F50, 0x62840F895B742BC8, 0x5EFC1DA922F50DC5, 0x1B3895B742BC8EA7, 0xEF4E35288013377, 0x7034C1EDC7954F9D, 0x404E07FFDCD9C4B4, 0x6C0D3C3112E9FC8B, 0xE93593735AD57C40, 0x5E74FB7D527D, 0x5C835ABF61CF41ED, 0xDF2950278C2E9C12, 0x35ABF61CF458FB68, 0x950278C2E9C125C8, 0xBF61CF458FB68DF2, 0x7E9C2E9C125C835A, 0xCA8064284EDAE000, 0xB011CE81CE7860C5, 0xF2D3F4033A9B8AE2, 0x2FF7880A1DE06DD0, 0x7182DD9DC3FCB499, 0xA4A77D973AB},
{0x8AE21EF6EA938B09, 0x37966C6ED5186501, 0x69DCB18F74253FB3, 0x3188241B31A56443, 0x9156C7D752C811D, 0x9CFAE79AFE751DE1, 0x8BF44341193A82F9, 0x34DAFBE7EE16D274, 0x272F0852BA272D8, 0xA0F247E8810D0FE5, 0x48E124BE4CC4D188, 0x4FDE2C9A5389, 0x44369DCB18F7403C, 0x11D3188241B31A56, 0xDE109156C7D752C8, 0x993912AE79AFE751, 0x34E708BDAC04CC86, 0x8C7E4CE5A9BBC962, 0xF269836E4C98DDD3, 0x45188E7965A38A0, 0xDAB83EB832EB62A0, 0xCCEFE1931E93559A, 0x775966B73B29F6D5, 0x45DBC312B900},
{0xB71EE1F7F5C9327, 0x8A5569830CE94076, 0x12961C17A5932157, 0xDD79C7E8EBB6086B, 0x2BEF8AB644F43951, 0x37277CB68D98CE33, 0xDE633F0A815B7506, 0x61740E19C3F2EFA4, 0x61B1E49FB5E4EABE, 0xA015247782FF386E, 0xE25E2C7B9F068D08, 0x5A5611C2C7A3, 0xD213F53791E68D00, 0x2EDE2F635D1EFA2E, 0xDA72EC5F8871204D, 0xDAEBFEACFFF3E491, 0x5F948C8E72BBF1CF, 0x4A440214B6EE743F, 0xD224FC96C70931D9, 0xEA00C3F488138831, 0x9D46231784C01FDC, 0xB12AA781AEC3B474, 0xE312A59BD123CE5A, 0x1FED35710EB4},
{0x72F7284A69378371, 0x3D4A5A89547E058, 0xB12975E3DAE2E152, 0x599E71CBADA705F9, 0x4ACD0B0B6F42CE9A, 0xE5285A0245577966, 0x6C038D909BB02FA1, 0x124374A6F770AF89, 0x99103DFE37CA79AF, 0x147E8A248FDBCAAE, 0xEB9B0A578010CFB9, 0x37F0B3678B6F, 0x5D470CF2D274DD99, 0xC8516258CB0C2B2B, 0xB43C53B94E11D2A6, 0x5ABE2DE626199F2D, 0x29D6C7C473EDC98, 0xE0376A892583E1DC, 0xC0CAA571F277C6A0, 0xD4F6AD7F88406328, 0xC9A2779B2F2431FD, 0xD7757D28491C9C9C, 0x3710D688A0ED993D, 0x4ADB9FE768DE},
{0x81F1C30C09FD33FC, 0xDBF51DCE3A9149C9, 0xE9CF78A0524C35B8, 0xC02099DC646FDE01, 0xB0594156B5517D78, 0xCDF2CD6BD4510E26, 0xA62E43C6D4ABA685, 0x6282F81A9AB8658, 0xD6D76B986C3AFC2D, 0x82003479185AC489, 0x68A227ED5A5D8D62, 0x4CB44C725522, 0x248D49A3572E2D8B, 0xD7958CBA82F9C02A, 0x8CAA9BD2ECD45A98, 0xD568F26B9E3F23BE, 0x6C2D5F812C90C433, 0xF1565E72D2FCBB81, 0x27E816D21960503D, 0xC557356BF112F986, 0x4C0F35DCE29E0B8B, 0xB5D66BBE22866AEA, 0xA93F73DFFDAB2E0A, 0x615CF5C957D3},
{0x516EE2A1BE021E2A, 0xF602D6E151658AD7, 0x26B24FB3189298B0, 0xD965FAF4CE85C95, 0xEFEF3DB9B3A4B775, 0xD851DD3FA8E08D31, 0x2DA32E186C78CE68, 0x143617DD482EE422, 0x667237E94436FC75, 0x1AC3465D96DCFDBB, 0x56D74ABF63E8D5D3, 0x5D7C60C0D2E4, 0xA30146117F0077FD, 0x9BE366E0CADBC188, 0xEF64080B2EACAD26, 0xA8FD83BF0D513C6, 0x877CB3DDB56170B2, 0xB35C3C73A225B6FC, 0xBF79CBB465569B88, 0x498384E224080C8B, 0xB2F0B94988649443, 0xB3DCD435A017EB4F, 0xE9941938991157FB, 0x21C1C22E5E5B},
{0xD40E007BD838CEA, 0xA6EFBD2F6C46FEC8, 0xDC1072B787D7CD36, 0x7204C616DD691C29, 0xF3C600AA941422BD, 0xB810967F5BD8F3A2, 0x53CCFBAE4D3DD147, 0xCC071945DE01CFF7, 0x6DD53CCD52E214A3, 0xB2C2FB56192E2E38, 0xD2B99B61C093CFD5, 0x51BE0034F0EA, 0x8107763EA961F872, 0x74B86F2CE50392D0, 0xDB4527F030D9F82D, 0xEC3F66A797FB122F, 0xF4DE67CF2F609807, 0xEFC422F586A5B1F2, 0xB765C11D7152D2E1, 0xB0A5BFC4FD2AC62B, 0x589DF808D4BB351A, 0x1165BA9E7035FA93, 0xE9B487C366AEC785, 0x586D2918F33C},
{0x6E3302C6FE0C0C01, 0xDFAC66DC6CEDA28C, 0xDED64C5EF280083F, 0x8B39B4C197F785CD, 0x11B93A8C64FD9206, 0x9AC84CC06813FCFF, 0xCF85682DC9D9B864, 0xC23496D96970C301, 0x5194BE86F6E26D90, 0x4DB579722DE163E0, 0x66DAEB4660E533AE, 0x15B525F2A541, 0x7C758374FFD93EC3, 0x2C7354CAF23E0942, 0xBD93A801DBC916D7, 0x47E4D764786D5DAC, 0x712497FC82C0471, 0x87311F4B3AF3FE32, 0xEFAEC8155C91650E, 0xE2169C5AD02053FE, 0xC96489E29375ADEB, 0x5E7D1381050F03CE, 0xB88C1A56DDD05F31, 0x6070D9E2F41},
{0x9ED7073D4D892D5E, 0x7A8ACF5D59CC31D7, 0x149DB0BEB6B3A2E1, 0xC059D51CC46D3357, 0xEE43544B33B041DD, 0x5CC5EB8BC024538F, 0x4B759EA5B9EAB631, 0xA335C8BC0AEEAFBC, 0xB03F67E326524765, 0x2C790108FA72A4B0, 0x789B5DA805C4192F, 0x64DEC5C9AB82, 0x36DAB776C6A6E1AD, 0x70788D740F12BB16, 0x678109B1BC9AEB8, 0x6CC747669CD9ABEF, 0xCBF25E90DDFDB9BA, 0x9186ABE61B8B423E, 0x29E06834AA38279D, 0x45176543D221EEC1, 0x761F084D3249B19E, 0xB968904364D0E464, 0x5DB85DA70B052289, 0x521E2DDB50A5},
{0x395783F790D29774, 0x112CEC9A5FB0FD8E, 0x2286B13D7C636B50, 0x3BB1C1FAABC848AE, 0xCEBD9A801EAB03DC, 0xD0D0F3042DC47BD3, 0xBA7CC91C76FBFC6F, 0x7E4B81D9BC252CC4, 0x791DA3C97B45B52E, 0x76E4B2A8663A7CDB, 0xB18F9D7CDF16DE77, 0x6738B89E9A90, 0xC5C400C8DEF67ACF, 0x7DB5C96374C369C2, 0x4DE65F1497C0251B, 0x3D6A0B0AA5A7DC1D, 0xCFF42CDA41FF0694, 0x13585BF9A20DF747, 0x29F5EA2387657EA2, 0x85F982D144BC9D02, 0x70BA26172B51F920, 0x7CDC5B7AD3069E68, 0xDA452B30229CE4DE, 0x5308C36EA06B},
{0xAC4F402D28A1B7D9, 0x1F9692D5D204DA19, 0x7B09C49F36556C65, 0x74E03DD0CC93BAA4, 0x2857AF2E2C697F78, 0xB5B97969D9A74314, 0x9B0B4C1B8B9C5804, 0x12FE23955636F0E, 0xB8E8FEC4456834F9, 0xF6E7C5B893C1F2AC, 0x5A45A12C0CF9B64, 0x4242B7D98CD1, 0x895BC47E5E99FE58, 0xCFD306BF78ED7A, 0x43394EBA61FCD38C, 0x83E94C74E7C77585, 0x9E944616E2627346, 0x9BA6856CF3432676, 0x2185C6AFF5533077, 0x67F7CB233436A703, 0x52D795D168AD54FF, 0xBB7BF59763DC0670, 0x79561A9B5335EFFB, 0x6F8E14E2EA1D},
{0x52170E4682673A4B, 0xAD4577028668C00, 0x105830C4E5B35043, 0xE44B518DCE2097C, 0x1DC57628AFA086C9, 0x7017D10868A9652D, 0xF52DAC7D308B4DED, 0xE5F8D6B44798B8A4, 0x860E5513916A8B0B, 0xEF1A2AE69403037, 0xFD7E1676F8DB8D34, 0x1DA40260AF34, 0x438DF92CAED981E9, 0xE0EC927187AF9BD2, 0x2C47A2EB752165A, 0x10A814019E74674B, 0xAD43DCF5C2393FE, 0x9EF40A6C20918C14, 0x827A35EE6A2A622C, 0xC5367CAADECCABBA, 0xDEC9E5F60CC017A0, 0x89393E2776CC5F44, 0x7AD261CF40C946E0, 0x69EC298FC2C5},
{0xE370D28A643127FE, 0x6484E527E4F15551, 0x3F59642BD5A34627, 0x85A03E71ECC4BDC1, 0x7B2E731CBACBC6B9, 0x70F5FDBD8FDA90B6, 0x24E12F3C9683795B, 0x35FAA7C6879A3C7C, 0xFF53C1E88A24C6E7, 0xE5DD61BDDC562FD5, 0xE68B1C39660B3261, 0x6259E2A86D74, 0x2982F0136CCDEF7A, 0x8848824CB25EDE31, 0x7BF8BC5D9CE7B4CD, 0x5A3A0205A555D497, 0x9240434A161CAB24, 0xFDB3CBB75FE9869F, 0xC97131D9A60D18C9, 0x9DB915412B8CB0B8, 0x5B7E4834AD58F24F, 0xDF6E9178CA871824, 0xF1259454624AC092, 0x1327C8999EB4},
{0x666280546751F204, 0x3124828432952042, 0x628126D710FA6B0A, 0x1D3B96F1B28EB258, 0xA3E698E6B79C0621, 0x5CFD4588D9A09890, 0x43A7B8C256D49EBA, 0xE2F94301C0032B74, 0x8953956AC6CA7C77, 0x7F8015DC765F106C, 0x82E4DDDD36ED8083, 0x133AE4EA2F71, 0xDBF063D1F1AF17B9, 0xCEC32E934E871629, 0xE2671C831AFAA693, 0x960B975DBBED5813, 0x203E4A33C527B48A, 0x423CD368EF5C02DB, 0x361633B23B9CEB74, 0x5F11CA4E0B5ECBDD, 0xAD9328EC4662A397, 0xEA2509539AEEDDBA, 0x15BB2346F14D8146, 0x2F2B9A05EEE},
{0x795D912BDEF015D7, 0x65E6C0F35599987E, 0x8BE785422F397093, 0xCD93F70F07BAA7DB, 0xF1A8945586B3C277, 0x26353E447C9BF58B, 0x4CD879A487B985CA, 0x9E680A1F08FF3F3F, 0xEA67CD5F51356E12, 0x501DDEE09936B7D1, 0x559A868F99683C3A, 0x23FA0B67D681, 0xEDDAB05F06B5A605, 0xC6E7FE44E0E20ACE, 0xDA2D7FCAF5C0C0EB, 0x7507BC508BE5F429, 0x7516F14BC559D8F0, 0x55DB0692A07CC717, 0x12F7611288A3B08B, 0x34ED3DD86C14B639, 0x2BCFE7EA6234CAAA, 0xA20E37F49CD7B313, 0xED785E90CA869C5F, 0x524FB4A9B68D},
{0xB24323DEA264A910, 0xFBB77EB1969BA34D, 0x6DFE6BD2DF0E62D, 0x4BA1D9212AAC1737, 0x6604456CC168CE0D, 0x1F045C2902E70B1A, 0xC30F3CF005747BBB, 0xD0808A1E60231D09, 0x616E5202B8B68AB9, 0x91279DE1E1F59C61, 0x17039A54DE74E351, 0x483F7B722965, 0xCA63AE6778B0F84E, 0x3920204D38EBDF19, 0xFB1FE6BAD523F1EC, 0x8B34EDE136AC2733, 0x7409325BA76B71BB, 0x987FACF98158EF9B, 0x3EBAB81D7CC6988B, 0x518A2D688F371575, 0xC77B4766A9D72BCA, 0xAF7343FE6E77A7C4, 0x54516072DE9FE449, 0x52E493B8BEDC},
{0x95B9273E98BEE101, 0x6CF2C2CC7C2F0D29, 0xEFE3B76E594AA11B, 0x3DDEDCDD1FE42241, 0xF7E15F986E39CC89, 0x3CF9E152B6FD333B, 0xE7F2CF0844AD69DD, 0xB792DFF3C762D02E, 0x3888F4A332FD9030, 0x8A4CC0E4C437575A, 0x833E2BA7BAF41403, 0x135FE5EBD4BB, 0x657D9769E52DAD91, 0x84951CC10B514173, 0x7678CDEC0CC5511B, 0xD4E7DB99FC763848, 0xC6ADD473DF8087CE, 0x842DE2D06829FA76, 0xD086DB2A4651BE48, 0xD0399255E5DAD344, 0x6B2EAEB21B8BB524, 0xF6DE9148F0694AEF, 0x5A85093194755805, 0x2570D86C9FCF},
{0xD665CD614A703CBD, 0x7251A4FFE04E2B30, 0x8AD6A13EAA0B07BC, 0x2AB5112D91260BE2, 0xF31D78441E75FDE5, 0x981D1D465A8768E6, 0x7AD08CCEE352CCDD, 0x31C6C60ACD409AC7, 0xDFC10AD642C330AA, 0x16DA3C495AE40C44, 0x89AB4B294D700C6D, 0x13081265A555, 0xB649623190FAD2EC, 0x9E0A9F4A626C11FD, 0xEF8A6A8092D66371, 0xEB9370EA38CC1EED, 0x74BF8D8667FFF12C, 0xF931EE21E90FE5CA, 0x5E180EC10EC59AE0, 0xBA6729A7EF221E52, 0xAEAB0D0AC6ED85F9, 0x2401EAF62859B015, 0xD309B49CD60C1B34, 0x2CBA9B452CC8}};
static const uint64_t v_3_torsion[20][2 * NWORDS64_FIELD] = {
{0xD89D89D89D8A493E, 0x9D89D89D89D89D89, 0x89D89D89D89D89D8, 0xD89D89D89D89D89D, 0x9D89D89D89D89D89, 0x8B389D89D89D89D8, 0xB4C6B9529F01D8C3, 0x1399AE2626262260, 0xDE85321D9D8185DF, 0x8451DC3FDF91784A, 0xFAEFD5E487381389, 0x6319EE6373CB, 0x3B13B13B13B1248D, 0x13B13B13B13B13B1, 0xB13B13B13B13B13B, 0x3B13B13B13B13B13, 0x13B13B13B13B13B1, 0x7A4B13B13B13B13B, 0xA30792A3BBCAECC7, 0x8E3262972F905537, 0x6EC1E1420B7BAD51, 0x3369C4F4190692FF, 0x9D6D588BD01A282C, 0x28F2E2C80A9},
{0x673D45AA630B09FB, 0x5673D45AA630AE95, 0x95673D45AA630AE9, 0xE95673D45AA630AE, 0xAE95673D45AA630A, 0xD4595673D45AA630, 0x6D7B45385F91ACC, 0x7FDE0F3B044702EF, 0xF1BFC4766FC2E18A, 0xD67138B8790E3167, 0x9EF75C6F0552A406, 0x2C5A25459904, 0xF6C4681424EE5801, 0xAF6C4681424EE5FA, 0xFAF6C4681424EE5F, 0x5FAF6C4681424EE5, 0xE5FAF6C4681424EE, 0x7FAFAF6C4681424E, 0x71E7F021FC96E1CF, 0xBD317223E4665091, 0x4D1B06EED834E4E, 0xF423F47B02EEF4B8, 0xA418B4D55C23C88, 0x94F95559E31},
{0xBC8EA75EFC1DB814, 0xDC562840F895B742, 0xEA75EFC1DA922F50, 0x62840F895B742BC8, 0x5EFC1DA922F50DC5, 0x1B3895B742BC8EA7, 0xEF4E35288013377, 0x7034C1EDC7954F9D, 0x404E07FFDCD9C4B4, 0x6C0D3C3112E9FC8B, 0xE93593735AD57C40, 0x5E74FB7D527D, 0x5C835ABF61CF41ED, 0xDF2950278C2E9C12, 0x35ABF61CF458FB68, 0x950278C2E9C125C8, 0xBF61CF458FB68DF2, 0x7E9C2E9C125C835A, 0xCA8064284EDAE000, 0xB011CE81CE7860C5, 0xF2D3F4033A9B8AE2, 0x2FF7880A1DE06DD0, 0x7182DD9DC3FCB499, 0xA4A77D973AB},
{0x8AE21EF6EA938B09, 0x37966C6ED5186501, 0x69DCB18F74253FB3, 0x3188241B31A56443, 0x9156C7D752C811D, 0x9CFAE79AFE751DE1, 0x8BF44341193A82F9, 0x34DAFBE7EE16D274, 0x272F0852BA272D8, 0xA0F247E8810D0FE5, 0x48E124BE4CC4D188, 0x4FDE2C9A5389, 0x44369DCB18F7403C, 0x11D3188241B31A56, 0xDE109156C7D752C8, 0x993912AE79AFE751, 0x34E708BDAC04CC86, 0x8C7E4CE5A9BBC962, 0xF269836E4C98DDD3, 0x45188E7965A38A0, 0xDAB83EB832EB62A0, 0xCCEFE1931E93559A, 0x775966B73B29F6D5, 0x45DBC312B900},
{0xB71EE1F7F5C9327, 0x8A5569830CE94076, 0x12961C17A5932157, 0xDD79C7E8EBB6086B, 0x2BEF8AB644F43951, 0x37277CB68D98CE33, 0xDE633F0A815B7506, 0x61740E19C3F2EFA4, 0x61B1E49FB5E4EABE, 0xA015247782FF386E, 0xE25E2C7B9F068D08, 0x5A5611C2C7A3, 0xD213F53791E68D00, 0x2EDE2F635D1EFA2E, 0xDA72EC5F8871204D, 0xDAEBFEACFFF3E491, 0x5F948C8E72BBF1CF, 0x4A440214B6EE743F, 0xD224FC96C70931D9, 0xEA00C3F488138831, 0x9D46231784C01FDC, 0xB12AA781AEC3B474, 0xE312A59BD123CE5A, 0x1FED35710EB4},
{0x72F7284A69378371, 0x3D4A5A89547E058, 0xB12975E3DAE2E152, 0x599E71CBADA705F9, 0x4ACD0B0B6F42CE9A, 0xE5285A0245577966, 0x6C038D909BB02FA1, 0x124374A6F770AF89, 0x99103DFE37CA79AF, 0x147E8A248FDBCAAE, 0xEB9B0A578010CFB9, 0x37F0B3678B6F, 0x5D470CF2D274DD99, 0xC8516258CB0C2B2B, 0xB43C53B94E11D2A6, 0x5ABE2DE626199F2D, 0x29D6C7C473EDC98, 0xE0376A892583E1DC, 0xC0CAA571F277C6A0, 0xD4F6AD7F88406328, 0xC9A2779B2F2431FD, 0xD7757D28491C9C9C, 0x3710D688A0ED993D, 0x4ADB9FE768DE},
{0x81F1C30C09FD33FC, 0xDBF51DCE3A9149C9, 0xE9CF78A0524C35B8, 0xC02099DC646FDE01, 0xB0594156B5517D78, 0xCDF2CD6BD4510E26, 0xA62E43C6D4ABA685, 0x6282F81A9AB8658, 0xD6D76B986C3AFC2D, 0x82003479185AC489, 0x68A227ED5A5D8D62, 0x4CB44C725522, 0x248D49A3572E2D8B, 0xD7958CBA82F9C02A, 0x8CAA9BD2ECD45A98, 0xD568F26B9E3F23BE, 0x6C2D5F812C90C433, 0xF1565E72D2FCBB81, 0x27E816D21960503D, 0xC557356BF112F986, 0x4C0F35DCE29E0B8B, 0xB5D66BBE22866AEA, 0xA93F73DFFDAB2E0A, 0x615CF5C957D3},
{0x516EE2A1BE021E2A, 0xF602D6E151658AD7, 0x26B24FB3189298B0, 0xD965FAF4CE85C95, 0xEFEF3DB9B3A4B775, 0xD851DD3FA8E08D31, 0x2DA32E186C78CE68, 0x143617DD482EE422, 0x667237E94436FC75, 0x1AC3465D96DCFDBB, 0x56D74ABF63E8D5D3, 0x5D7C60C0D2E4, 0xA30146117F0077FD, 0x9BE366E0CADBC188, 0xEF64080B2EACAD26, 0xA8FD83BF0D513C6, 0x877CB3DDB56170B2, 0xB35C3C73A225B6FC, 0xBF79CBB465569B88, 0x498384E224080C8B, 0xB2F0B94988649443, 0xB3DCD435A017EB4F, 0xE9941938991157FB, 0x21C1C22E5E5B},
{0xD40E007BD838CEA, 0xA6EFBD2F6C46FEC8, 0xDC1072B787D7CD36, 0x7204C616DD691C29, 0xF3C600AA941422BD, 0xB810967F5BD8F3A2, 0x53CCFBAE4D3DD147, 0xCC071945DE01CFF7, 0x6DD53CCD52E214A3, 0xB2C2FB56192E2E38, 0xD2B99B61C093CFD5, 0x51BE0034F0EA, 0x8107763EA961F872, 0x74B86F2CE50392D0, 0xDB4527F030D9F82D, 0xEC3F66A797FB122F, 0xF4DE67CF2F609807, 0xEFC422F586A5B1F2, 0xB765C11D7152D2E1, 0xB0A5BFC4FD2AC62B, 0x589DF808D4BB351A, 0x1165BA9E7035FA93, 0xE9B487C366AEC785, 0x586D2918F33C},
{0x6E3302C6FE0C0C01, 0xDFAC66DC6CEDA28C, 0xDED64C5EF280083F, 0x8B39B4C197F785CD, 0x11B93A8C64FD9206, 0x9AC84CC06813FCFF, 0xCF85682DC9D9B864, 0xC23496D96970C301, 0x5194BE86F6E26D90, 0x4DB579722DE163E0, 0x66DAEB4660E533AE, 0x15B525F2A541, 0x7C758374FFD93EC3, 0x2C7354CAF23E0942, 0xBD93A801DBC916D7, 0x47E4D764786D5DAC, 0x712497FC82C0471, 0x87311F4B3AF3FE32, 0xEFAEC8155C91650E, 0xE2169C5AD02053FE, 0xC96489E29375ADEB, 0x5E7D1381050F03CE, 0xB88C1A56DDD05F31, 0x6070D9E2F41},
{0x9ED7073D4D892D5E, 0x7A8ACF5D59CC31D7, 0x149DB0BEB6B3A2E1, 0xC059D51CC46D3357, 0xEE43544B33B041DD, 0x5CC5EB8BC024538F, 0x4B759EA5B9EAB631, 0xA335C8BC0AEEAFBC, 0xB03F67E326524765, 0x2C790108FA72A4B0, 0x789B5DA805C4192F, 0x64DEC5C9AB82, 0x36DAB776C6A6E1AD, 0x70788D740F12BB16, 0x678109B1BC9AEB8, 0x6CC747669CD9ABEF, 0xCBF25E90DDFDB9BA, 0x9186ABE61B8B423E, 0x29E06834AA38279D, 0x45176543D221EEC1, 0x761F084D3249B19E, 0xB968904364D0E464, 0x5DB85DA70B052289, 0x521E2DDB50A5},
{0x395783F790D29774, 0x112CEC9A5FB0FD8E, 0x2286B13D7C636B50, 0x3BB1C1FAABC848AE, 0xCEBD9A801EAB03DC, 0xD0D0F3042DC47BD3, 0xBA7CC91C76FBFC6F, 0x7E4B81D9BC252CC4, 0x791DA3C97B45B52E, 0x76E4B2A8663A7CDB, 0xB18F9D7CDF16DE77, 0x6738B89E9A90, 0xC5C400C8DEF67ACF, 0x7DB5C96374C369C2, 0x4DE65F1497C0251B, 0x3D6A0B0AA5A7DC1D, 0xCFF42CDA41FF0694, 0x13585BF9A20DF747, 0x29F5EA2387657EA2, 0x85F982D144BC9D02, 0x70BA26172B51F920, 0x7CDC5B7AD3069E68, 0xDA452B30229CE4DE, 0x5308C36EA06B},
{0xAC4F402D28A1B7D9, 0x1F9692D5D204DA19, 0x7B09C49F36556C65, 0x74E03DD0CC93BAA4, 0x2857AF2E2C697F78, 0xB5B97969D9A74314, 0x9B0B4C1B8B9C5804, 0x12FE23955636F0E, 0xB8E8FEC4456834F9, 0xF6E7C5B893C1F2AC, 0x5A45A12C0CF9B64, 0x4242B7D98CD1, 0x895BC47E5E99FE58, 0xCFD306BF78ED7A, 0x43394EBA61FCD38C, 0x83E94C74E7C77585, 0x9E944616E2627346, 0x9BA6856CF3432676, 0x2185C6AFF5533077, 0x67F7CB233436A703, 0x52D795D168AD54FF, 0xBB7BF59763DC0670, 0x79561A9B5335EFFB, 0x6F8E14E2EA1D},
{0x52170E4682673A4B, 0xAD4577028668C00, 0x105830C4E5B35043, 0xE44B518DCE2097C, 0x1DC57628AFA086C9, 0x7017D10868A9652D, 0xF52DAC7D308B4DED, 0xE5F8D6B44798B8A4, 0x860E5513916A8B0B, 0xEF1A2AE69403037, 0xFD7E1676F8DB8D34, 0x1DA40260AF34, 0x438DF92CAED981E9, 0xE0EC927187AF9BD2, 0x2C47A2EB752165A, 0x10A814019E74674B, 0xAD43DCF5C2393FE, 0x9EF40A6C20918C14, 0x827A35EE6A2A622C, 0xC5367CAADECCABBA, 0xDEC9E5F60CC017A0, 0x89393E2776CC5F44, 0x7AD261CF40C946E0, 0x69EC298FC2C5},
{0xE370D28A643127FE, 0x6484E527E4F15551, 0x3F59642BD5A34627, 0x85A03E71ECC4BDC1, 0x7B2E731CBACBC6B9, 0x70F5FDBD8FDA90B6, 0x24E12F3C9683795B, 0x35FAA7C6879A3C7C, 0xFF53C1E88A24C6E7, 0xE5DD61BDDC562FD5, 0xE68B1C39660B3261, 0x6259E2A86D74, 0x2982F0136CCDEF7A, 0x8848824CB25EDE31, 0x7BF8BC5D9CE7B4CD, 0x5A3A0205A555D497, 0x9240434A161CAB24, 0xFDB3CBB75FE9869F, 0xC97131D9A60D18C9, 0x9DB915412B8CB0B8, 0x5B7E4834AD58F24F, 0xDF6E9178CA871824, 0xF1259454624AC092, 0x1327C8999EB4},
{0x666280546751F204, 0x3124828432952042, 0x628126D710FA6B0A, 0x1D3B96F1B28EB258, 0xA3E698E6B79C0621, 0x5CFD4588D9A09890, 0x43A7B8C256D49EBA, 0xE2F94301C0032B74, 0x8953956AC6CA7C77, 0x7F8015DC765F106C, 0x82E4DDDD36ED8083, 0x133AE4EA2F71, 0xDBF063D1F1AF17B9, 0xCEC32E934E871629, 0xE2671C831AFAA693, 0x960B975DBBED5813, 0x203E4A33C527B48A, 0x423CD368EF5C02DB, 0x361633B23B9CEB74, 0x5F11CA4E0B5ECBDD, 0xAD9328EC4662A397, 0xEA2509539AEEDDBA, 0x15BB2346F14D8146, 0x2F2B9A05EEE},
{0x795D912BDEF015D7, 0x65E6C0F35599987E, 0x8BE785422F397093, 0xCD93F70F07BAA7DB, 0xF1A8945586B3C277, 0x26353E447C9BF58B, 0x4CD879A487B985CA, 0x9E680A1F08FF3F3F, 0xEA67CD5F51356E12, 0x501DDEE09936B7D1, 0x559A868F99683C3A, 0x23FA0B67D681, 0xEDDAB05F06B5A605, 0xC6E7FE44E0E20ACE, 0xDA2D7FCAF5C0C0EB, 0x7507BC508BE5F429, 0x7516F14BC559D8F0, 0x55DB0692A07CC717, 0x12F7611288A3B08B, 0x34ED3DD86C14B639, 0x2BCFE7EA6234CAAA, 0xA20E37F49CD7B313, 0xED785E90CA869C5F, 0x524FB4A9B68D},
{0xB24323DEA264A910, 0xFBB77EB1969BA34D, 0x6DFE6BD2DF0E62D, 0x4BA1D9212AAC1737, 0x6604456CC168CE0D, 0x1F045C2902E70B1A, 0xC30F3CF005747BBB, 0xD0808A1E60231D09, 0x616E5202B8B68AB9, 0x91279DE1E1F59C61, 0x17039A54DE74E351, 0x483F7B722965, 0xCA63AE6778B0F84E, 0x3920204D38EBDF19, 0xFB1FE6BAD523F1EC, 0x8B34EDE136AC2733, 0x7409325BA76B71BB, 0x987FACF98158EF9B, 0x3EBAB81D7CC6988B, 0x518A2D688F371575, 0xC77B4766A9D72BCA, 0xAF7343FE6E77A7C4, 0x54516072DE9FE449, 0x52E493B8BEDC},
{0x95B9273E98BEE101, 0x6CF2C2CC7C2F0D29, 0xEFE3B76E594AA11B, 0x3DDEDCDD1FE42241, 0xF7E15F986E39CC89, 0x3CF9E152B6FD333B, 0xE7F2CF0844AD69DD, 0xB792DFF3C762D02E, 0x3888F4A332FD9030, 0x8A4CC0E4C437575A, 0x833E2BA7BAF41403, 0x135FE5EBD4BB, 0x657D9769E52DAD91, 0x84951CC10B514173, 0x7678CDEC0CC5511B, 0xD4E7DB99FC763848, 0xC6ADD473DF8087CE, 0x842DE2D06829FA76, 0xD086DB2A4651BE48, 0xD0399255E5DAD344, 0x6B2EAEB21B8BB524, 0xF6DE9148F0694AEF, 0x5A85093194755805, 0x2570D86C9FCF},
{0xD665CD614A703CBD, 0x7251A4FFE04E2B30, 0x8AD6A13EAA0B07BC, 0x2AB5112D91260BE2, 0xF31D78441E75FDE5, 0x981D1D465A8768E6, 0x7AD08CCEE352CCDD, 0x31C6C60ACD409AC7, 0xDFC10AD642C330AA, 0x16DA3C495AE40C44, 0x89AB4B294D700C6D, 0x13081265A555, 0xB649623190FAD2EC, 0x9E0A9F4A626C11FD, 0xEF8A6A8092D66371, 0xEB9370EA38CC1EED, 0x74BF8D8667FFF12C, 0xF931EE21E90FE5CA, 0x5E180EC10EC59AE0, 0xBA6729A7EF221E52, 0xAEAB0D0AC6ED85F9, 0x2401EAF62859B015, 0xD309B49CD60C1B34, 0x2CBA9B452CC8}
};
// Setting up macro defines and including GF(p), GF(p^2), curve, isogeny and kex functions
#define fpcopy fpcopy751

View File

@ -1,291 +1,291 @@
/********************************************************************************************
* SIDH: an efficient supersingular isogeny cryptography library
*
* Abstract: internal header file for P751
*********************************************************************************************/
#ifndef P751_INTERNAL_H
#define P751_INTERNAL_H
#include "../config.h"
#if (TARGET == TARGET_AMD64)
#define NWORDS_FIELD 12 // Number of words of a 751-bit field element
#define p751_ZERO_WORDS 5 // Number of "0" digits in the least significant part of p751 + 1
#elif (TARGET == TARGET_x86)
#define NWORDS_FIELD 24
#define p751_ZERO_WORDS 11
#elif (TARGET == TARGET_ARM)
#define NWORDS_FIELD 24
#define p751_ZERO_WORDS 11
#elif (TARGET == TARGET_ARM64)
#define NWORDS_FIELD 12
#define p751_ZERO_WORDS 5
#endif
// Basic constants
#define NBITS_FIELD 751
#define MAXBITS_FIELD 768
#define MAXWORDS_FIELD ((MAXBITS_FIELD + RADIX - 1) / RADIX) // Max. number of words to represent field elements
#define NWORDS64_FIELD ((NBITS_FIELD + 63) / 64) // Number of 64-bit words of a 751-bit field element
#define NBITS_ORDER 384
#define NWORDS_ORDER ((NBITS_ORDER + RADIX - 1) / RADIX) // Number of words of oA and oB, where oA and oB are the subgroup orders of Alice and Bob, resp.
#define NWORDS64_ORDER ((NBITS_ORDER + 63) / 64) // Number of 64-bit words of a 384-bit element
#define MAXBITS_ORDER NBITS_ORDER
#define ALICE 0
#define BOB 1
#define OALICE_BITS 372
#define OBOB_BITS 379
#define OBOB_EXPON 239
#define MASK_ALICE 0x0F
#define MASK_BOB 0x03
#define PRIME p751
#define PARAM_A 6
#define PARAM_C 1
// Fixed parameters for isogeny tree computation
#define MAX_INT_POINTS_ALICE 8
#define MAX_INT_POINTS_BOB 10
#define MAX_Alice 186
#define MAX_Bob 239
#define MSG_BYTES 32
#define SECRETKEY_A_BYTES ((OALICE_BITS + 7) / 8)
#define SECRETKEY_B_BYTES ((OBOB_BITS - 1 + 7) / 8)
#define FP2_ENCODED_BYTES 2 * ((NBITS_FIELD + 7) / 8)
#ifdef COMPRESS
#define MASK2_BOB 0x00
#define MASK3_BOB 0xFF
#define ORDER_A_ENCODED_BYTES SECRETKEY_A_BYTES
#define ORDER_B_ENCODED_BYTES SECRETKEY_B_BYTES
#define COMPRESSED_CHUNK_CT (3 * ORDER_A_ENCODED_BYTES + FP2_ENCODED_BYTES + 2)
#define UNCOMPRESSEDPK_BYTES 564
// Table sizes used by the Entangled basis generation
#define TABLE_R_LEN 17
#define TABLE_V_LEN 34
// Parameters for discrete log computations
// Binary Pohlig-Hellman reduced to smaller logs of order ell^W
#define W_2 4
#define W_3 5
// ell^w
#define ELL2_W (1 << W_2)
#define ELL3_W 243 // W_3 = 5
// ell^(e mod w)
#define ELL2_EMODW (1 << (OALICE_BITS % W_2))
#define ELL3_EMODW 81
// # of digits in the discrete log
#define DLEN_2 93 // ceil(eA/W_2)
#define DLEN_3 48 // ceil(eB/W_3)
// Length of the optimal strategy path for Pohlig-Hellman
#define PLEN_2 94
#define PLEN_3 49
#endif
// SIDH's basic element definitions and point representations
typedef digit_t felm_t[NWORDS_FIELD]; // Datatype for representing 751-bit field elements (768-bit max.)
typedef digit_t dfelm_t[2 * NWORDS_FIELD]; // Datatype for representing double-precision 2x751-bit field elements (2x768-bit max.)
typedef felm_t f2elm_t[2]; // Datatype for representing quadratic extension field elements GF(p751^2)
typedef struct {
f2elm_t X;
f2elm_t Z;
} point_proj; // Point representation in projective XZ Montgomery coordinates.
typedef point_proj point_proj_t[1];
#ifdef COMPRESS
typedef struct {
f2elm_t X;
f2elm_t Y;
f2elm_t Z;
} point_full_proj; // Point representation in full projective XYZ Montgomery coordinates
typedef point_full_proj point_full_proj_t[1];
typedef struct {
f2elm_t x;
f2elm_t y;
} point_affine; // Point representation in affine coordinates.
typedef point_affine point_t[1];
typedef f2elm_t publickey_t[3];
#endif
/**************** Function prototypes ****************/
/************* Multiprecision functions **************/
// Copy wordsize digits, c = a, where lng(a) = nwords
static void copy_words(const digit_t *a, digit_t *c, const unsigned int nwords);
// Multiprecision addition, c = a+b, where lng(a) = lng(b) = nwords. Returns the carry bit
static unsigned int mp_add(const digit_t *a, const digit_t *b, digit_t *c, const unsigned int nwords);
// 751-bit multiprecision addition, c = a+b
static void mp_add751(const digit_t *a, const digit_t *b, digit_t *c);
void oqs_kem_sike_mp_add751_asm(const digit_t *a, const digit_t *b, digit_t *c);
// Multiprecision subtraction, c = a-b, where lng(a) = lng(b) = nwords. Returns the borrow bit
static unsigned int mp_sub(const digit_t *a, const digit_t *b, digit_t *c, const unsigned int nwords);
// 2x751-bit multiprecision subtraction followed by addition with p751*2^768, c = a-b+(p751*2^768) if a-b < 0, otherwise c=a-b
void oqs_kem_sike_mp_subaddx2_asm(const digit_t *a, const digit_t *b, digit_t *c);
void oqs_kem_sike_mp_subadd751x2_asm(const digit_t *a, const digit_t *b, digit_t *c);
// Double 2x751-bit multiprecision subtraction, c = c-a-b, where c > a and c > b
void oqs_kem_sike_mp_dblsub751x2_asm(const digit_t *a, const digit_t *b, digit_t *c);
// Multiprecision left shift
static void mp_shiftleft(digit_t *x, unsigned int shift, const unsigned int nwords);
// Multiprecision right shift by one
static void mp_shiftr1(digit_t *x, const unsigned int nwords);
// Multiprecision left right shift by one
static void mp_shiftl1(digit_t *x, const unsigned int nwords);
// Digit multiplication, digit * digit -> 2-digit result
static void digit_x_digit(const digit_t a, const digit_t b, digit_t *c);
// Multiprecision comba multiply, c = a*b, where lng(a) = lng(b) = nwords.
static void mp_mul(const digit_t *a, const digit_t *b, digit_t *c, const unsigned int nwords);
/************ Field arithmetic functions *************/
// Copy of a field element, c = a
static void fpcopy751(const digit_t *a, digit_t *c);
// Zeroing a field element, a = 0
static void fpzero751(digit_t *a);
// Non constant-time comparison of two field elements. If a = b return TRUE, otherwise, return FALSE
static bool fpequal751_non_constant_time(const digit_t *a, const digit_t *b);
// Modular addition, c = a+b mod p751
extern void fpadd751(const digit_t *a, const digit_t *b, digit_t *c);
extern void oqs_kem_sike_fpadd751_asm(const digit_t *a, const digit_t *b, digit_t *c);
// Modular subtraction, c = a-b mod p751
extern void fpsub751(const digit_t *a, const digit_t *b, digit_t *c);
extern void oqs_kem_sike_fpsub751_asm(const digit_t *a, const digit_t *b, digit_t *c);
// Modular negation, a = -a mod p751
extern void fpneg751(digit_t *a);
// Modular division by two, c = a/2 mod p751.
static void fpdiv2_751(const digit_t *a, digit_t *c);
// Modular correction to reduce field element a in [0, 2*p751-1] to [0, p751-1].
static void fpcorrection751(digit_t *a);
// 751-bit Montgomery reduction, c = a mod p
static void rdc_mont(digit_t *a, digit_t *c);
void oqs_kem_sike_rdc751_asm(digit_t *ma, digit_t *mc);
// Field multiplication using Montgomery arithmetic, c = a*b*R^-1 mod p751, where R=2^768
static void fpmul751_mont(const digit_t *a, const digit_t *b, digit_t *c);
void oqs_kem_sike_mul751_asm(const digit_t *a, const digit_t *b, digit_t *c);
// Field squaring using Montgomery arithmetic, c = a*b*R^-1 mod p751, where R=2^768
static void fpsqr751_mont(const digit_t *ma, digit_t *mc);
// Conversion to Montgomery representation
static void to_mont(const digit_t *a, digit_t *mc);
// Conversion from Montgomery representation to standard representation
static void from_mont(const digit_t *ma, digit_t *c);
// Field inversion, a = a^-1 in GF(p751)
static void fpinv751_mont(digit_t *a);
// Field inversion, a = a^-1 in GF(p751) using the binary GCD
static void fpinv751_mont_bingcd(digit_t *a);
// Chain to compute (p751-3)/4 using Montgomery arithmetic
static void fpinv751_chain_mont(digit_t *a);
/************ GF(p^2) arithmetic functions *************/
// Copy of a GF(p751^2) element, c = a
static void fp2copy751(const f2elm_t a, f2elm_t c);
// Zeroing a GF(p751^2) element, a = 0
static void fp2zero751(f2elm_t a);
// GF(p751^2) negation, a = -a in GF(p751^2)
static void fp2neg751(f2elm_t a);
// GF(p751^2) addition, c = a+b in GF(p751^2)
extern void fp2add751(const f2elm_t a, const f2elm_t b, f2elm_t c);
// GF(p751^2) subtraction, c = a-b in GF(p751^2)
extern void fp2sub751(const f2elm_t a, const f2elm_t b, f2elm_t c);
// GF(p751^2) division by two, c = a/2 in GF(p751^2)
static void fp2div2_751(const f2elm_t a, f2elm_t c);
// Modular correction, a = a in GF(p751^2)
static void fp2correction751(f2elm_t a);
// GF(p751^2) squaring using Montgomery arithmetic, c = a^2 in GF(p751^2)
static void fp2sqr751_mont(const f2elm_t a, f2elm_t c);
// GF(p751^2) multiplication using Montgomery arithmetic, c = a*b in GF(p751^2)
static void fp2mul751_mont(const f2elm_t a, const f2elm_t b, f2elm_t c);
// Conversion of a GF(p751^2) element to Montgomery representation
static void to_fp2mont(const f2elm_t a, f2elm_t mc);
// Conversion of a GF(p751^2) element from Montgomery representation to standard representation
static void from_fp2mont(const f2elm_t ma, f2elm_t c);
// GF(p751^2) inversion using Montgomery arithmetic, a = (a0-i*a1)/(a0^2+a1^2)
static void fp2inv751_mont(f2elm_t a);
// GF(p751^2) inversion, a = (a0-i*a1)/(a0^2+a1^2), GF(p751) inversion done using the binary GCD
static void fp2inv751_mont_bingcd(f2elm_t a);
// n-way Montgomery inversion
static void mont_n_way_inv(const f2elm_t *vec, const int n, f2elm_t *out);
/************ Elliptic curve and isogeny functions *************/
// Computes the j-invariant of a Montgomery curve with projective constant.
static void j_inv(const f2elm_t A, const f2elm_t C, f2elm_t jinv);
// Simultaneous doubling and differential addition.
static void xDBLADD(point_proj_t P, point_proj_t Q, const f2elm_t xPQ, const f2elm_t A24);
// Doubling of a Montgomery point in projective coordinates (X:Z).
static void xDBL(const point_proj_t P, point_proj_t Q, const f2elm_t A24plus, const f2elm_t C24);
// Computes [2^e](X:Z) on Montgomery curve with projective constant via e repeated doublings.
static void xDBLe(const point_proj_t P, point_proj_t Q, const f2elm_t A24plus, const f2elm_t C24, const int e);
// Differential addition.
static void xADD(point_proj_t P, const point_proj_t Q, const f2elm_t xPQ);
// Computes the corresponding 4-isogeny of a projective Montgomery point (X4:Z4) of order 4.
static void get_4_isog(const point_proj_t P, f2elm_t A24plus, f2elm_t C24, f2elm_t *coeff);
// Evaluates the isogeny at the point (X:Z) in the domain of the isogeny.
static void eval_4_isog(point_proj_t P, f2elm_t *coeff);
// Tripling of a Montgomery point in projective coordinates (X:Z).
static void xTPL(const point_proj_t P, point_proj_t Q, const f2elm_t A24minus, const f2elm_t A24plus);
// Computes [3^e](X:Z) on Montgomery curve with projective constant via e repeated triplings.
static void xTPLe(const point_proj_t P, point_proj_t Q, const f2elm_t A24minus, const f2elm_t A24plus, const int e);
// Computes the corresponding 3-isogeny of a projective Montgomery point (X3:Z3) of order 3.
static void get_3_isog(const point_proj_t P, f2elm_t A24minus, f2elm_t A24plus, f2elm_t *coeff);
// Computes the 3-isogeny R=phi(X:Z), given projective point (X3:Z3) of order 3 on a Montgomery curve and a point P with coefficients given in coeff.
static void eval_3_isog(point_proj_t Q, const f2elm_t *coeff);
// 3-way simultaneous inversion
static void inv_3_way(f2elm_t z1, f2elm_t z2, f2elm_t z3);
// Given the x-coordinates of P, Q, and R, returns the value A corresponding to the Montgomery curve E_A: y^2=x^3+A*x^2+x such that R=Q-P on E_A.
static void get_A(const f2elm_t xP, const f2elm_t xQ, const f2elm_t xR, f2elm_t A);
#endif
/********************************************************************************************
* SIDH: an efficient supersingular isogeny cryptography library
*
* Abstract: internal header file for P751
*********************************************************************************************/
#ifndef P751_INTERNAL_H
#define P751_INTERNAL_H
#include "../config.h"
#if (TARGET == TARGET_AMD64)
#define NWORDS_FIELD 12 // Number of words of a 751-bit field element
#define p751_ZERO_WORDS 5 // Number of "0" digits in the least significant part of p751 + 1
#elif (TARGET == TARGET_x86)
#define NWORDS_FIELD 24
#define p751_ZERO_WORDS 11
#elif (TARGET == TARGET_ARM)
#define NWORDS_FIELD 24
#define p751_ZERO_WORDS 11
#elif (TARGET == TARGET_ARM64)
#define NWORDS_FIELD 12
#define p751_ZERO_WORDS 5
#endif
// Basic constants
#define NBITS_FIELD 751
#define MAXBITS_FIELD 768
#define MAXWORDS_FIELD ((MAXBITS_FIELD + RADIX - 1) / RADIX) // Max. number of words to represent field elements
#define NWORDS64_FIELD ((NBITS_FIELD + 63) / 64) // Number of 64-bit words of a 751-bit field element
#define NBITS_ORDER 384
#define NWORDS_ORDER ((NBITS_ORDER + RADIX - 1) / RADIX) // Number of words of oA and oB, where oA and oB are the subgroup orders of Alice and Bob, resp.
#define NWORDS64_ORDER ((NBITS_ORDER + 63) / 64) // Number of 64-bit words of a 384-bit element
#define MAXBITS_ORDER NBITS_ORDER
#define ALICE 0
#define BOB 1
#define OALICE_BITS 372
#define OBOB_BITS 379
#define OBOB_EXPON 239
#define MASK_ALICE 0x0F
#define MASK_BOB 0x03
#define PRIME p751
#define PARAM_A 6
#define PARAM_C 1
// Fixed parameters for isogeny tree computation
#define MAX_INT_POINTS_ALICE 8
#define MAX_INT_POINTS_BOB 10
#define MAX_Alice 186
#define MAX_Bob 239
#define MSG_BYTES 32
#define SECRETKEY_A_BYTES ((OALICE_BITS + 7) / 8)
#define SECRETKEY_B_BYTES ((OBOB_BITS - 1 + 7) / 8)
#define FP2_ENCODED_BYTES 2 * ((NBITS_FIELD + 7) / 8)
#ifdef COMPRESS
#define MASK2_BOB 0x00
#define MASK3_BOB 0xFF
#define ORDER_A_ENCODED_BYTES SECRETKEY_A_BYTES
#define ORDER_B_ENCODED_BYTES SECRETKEY_B_BYTES
#define COMPRESSED_CHUNK_CT (3 * ORDER_A_ENCODED_BYTES + FP2_ENCODED_BYTES + 2)
#define UNCOMPRESSEDPK_BYTES 564
// Table sizes used by the Entangled basis generation
#define TABLE_R_LEN 17
#define TABLE_V_LEN 34
// Parameters for discrete log computations
// Binary Pohlig-Hellman reduced to smaller logs of order ell^W
#define W_2 4
#define W_3 5
// ell^w
#define ELL2_W (1 << W_2)
#define ELL3_W 243 // W_3 = 5
// ell^(e mod w)
#define ELL2_EMODW (1 << (OALICE_BITS % W_2))
#define ELL3_EMODW 81
// # of digits in the discrete log
#define DLEN_2 93 // ceil(eA/W_2)
#define DLEN_3 48 // ceil(eB/W_3)
// Length of the optimal strategy path for Pohlig-Hellman
#define PLEN_2 94
#define PLEN_3 49
#endif
// SIDH's basic element definitions and point representations
typedef digit_t felm_t[NWORDS_FIELD]; // Datatype for representing 751-bit field elements (768-bit max.)
typedef digit_t dfelm_t[2 * NWORDS_FIELD]; // Datatype for representing double-precision 2x751-bit field elements (2x768-bit max.)
typedef felm_t f2elm_t[2]; // Datatype for representing quadratic extension field elements GF(p751^2)
typedef struct {
f2elm_t X;
f2elm_t Z;
} point_proj; // Point representation in projective XZ Montgomery coordinates.
typedef point_proj point_proj_t[1];
#ifdef COMPRESS
typedef struct {
f2elm_t X;
f2elm_t Y;
f2elm_t Z;
} point_full_proj; // Point representation in full projective XYZ Montgomery coordinates
typedef point_full_proj point_full_proj_t[1];
typedef struct {
f2elm_t x;
f2elm_t y;
} point_affine; // Point representation in affine coordinates.
typedef point_affine point_t[1];
typedef f2elm_t publickey_t[3];
#endif
/**************** Function prototypes ****************/
/************* Multiprecision functions **************/
// Copy wordsize digits, c = a, where lng(a) = nwords
static void copy_words(const digit_t *a, digit_t *c, const unsigned int nwords);
// Multiprecision addition, c = a+b, where lng(a) = lng(b) = nwords. Returns the carry bit
static unsigned int mp_add(const digit_t *a, const digit_t *b, digit_t *c, const unsigned int nwords);
// 751-bit multiprecision addition, c = a+b
static void mp_add751(const digit_t *a, const digit_t *b, digit_t *c);
void oqs_kem_sike_mp_add751_asm(const digit_t *a, const digit_t *b, digit_t *c);
// Multiprecision subtraction, c = a-b, where lng(a) = lng(b) = nwords. Returns the borrow bit
static unsigned int mp_sub(const digit_t *a, const digit_t *b, digit_t *c, const unsigned int nwords);
// 2x751-bit multiprecision subtraction followed by addition with p751*2^768, c = a-b+(p751*2^768) if a-b < 0, otherwise c=a-b
void oqs_kem_sike_mp_subaddx2_asm(const digit_t *a, const digit_t *b, digit_t *c);
void oqs_kem_sike_mp_subadd751x2_asm(const digit_t *a, const digit_t *b, digit_t *c);
// Double 2x751-bit multiprecision subtraction, c = c-a-b, where c > a and c > b
void oqs_kem_sike_mp_dblsub751x2_asm(const digit_t *a, const digit_t *b, digit_t *c);
// Multiprecision left shift
static void mp_shiftleft(digit_t *x, unsigned int shift, const unsigned int nwords);
// Multiprecision right shift by one
static void mp_shiftr1(digit_t *x, const unsigned int nwords);
// Multiprecision left right shift by one
static void mp_shiftl1(digit_t *x, const unsigned int nwords);
// Digit multiplication, digit * digit -> 2-digit result
static void digit_x_digit(const digit_t a, const digit_t b, digit_t *c);
// Multiprecision comba multiply, c = a*b, where lng(a) = lng(b) = nwords.
static void mp_mul(const digit_t *a, const digit_t *b, digit_t *c, const unsigned int nwords);
/************ Field arithmetic functions *************/
// Copy of a field element, c = a
static void fpcopy751(const digit_t *a, digit_t *c);
// Zeroing a field element, a = 0
static void fpzero751(digit_t *a);
// Non constant-time comparison of two field elements. If a = b return TRUE, otherwise, return FALSE
static bool fpequal751_non_constant_time(const digit_t *a, const digit_t *b);
// Modular addition, c = a+b mod p751
extern void fpadd751(const digit_t *a, const digit_t *b, digit_t *c);
extern void oqs_kem_sike_fpadd751_asm(const digit_t *a, const digit_t *b, digit_t *c);
// Modular subtraction, c = a-b mod p751
extern void fpsub751(const digit_t *a, const digit_t *b, digit_t *c);
extern void oqs_kem_sike_fpsub751_asm(const digit_t *a, const digit_t *b, digit_t *c);
// Modular negation, a = -a mod p751
extern void fpneg751(digit_t *a);
// Modular division by two, c = a/2 mod p751.
static void fpdiv2_751(const digit_t *a, digit_t *c);
// Modular correction to reduce field element a in [0, 2*p751-1] to [0, p751-1].
static void fpcorrection751(digit_t *a);
// 751-bit Montgomery reduction, c = a mod p
static void rdc_mont(digit_t *a, digit_t *c);
void oqs_kem_sike_rdc751_asm(digit_t *ma, digit_t *mc);
// Field multiplication using Montgomery arithmetic, c = a*b*R^-1 mod p751, where R=2^768
static void fpmul751_mont(const digit_t *a, const digit_t *b, digit_t *c);
void oqs_kem_sike_mul751_asm(const digit_t *a, const digit_t *b, digit_t *c);
// Field squaring using Montgomery arithmetic, c = a*b*R^-1 mod p751, where R=2^768
static void fpsqr751_mont(const digit_t *ma, digit_t *mc);
// Conversion to Montgomery representation
static void to_mont(const digit_t *a, digit_t *mc);
// Conversion from Montgomery representation to standard representation
static void from_mont(const digit_t *ma, digit_t *c);
// Field inversion, a = a^-1 in GF(p751)
static void fpinv751_mont(digit_t *a);
// Field inversion, a = a^-1 in GF(p751) using the binary GCD
static void fpinv751_mont_bingcd(digit_t *a);
// Chain to compute (p751-3)/4 using Montgomery arithmetic
static void fpinv751_chain_mont(digit_t *a);
/************ GF(p^2) arithmetic functions *************/
// Copy of a GF(p751^2) element, c = a
static void fp2copy751(const f2elm_t a, f2elm_t c);
// Zeroing a GF(p751^2) element, a = 0
static void fp2zero751(f2elm_t a);
// GF(p751^2) negation, a = -a in GF(p751^2)
static void fp2neg751(f2elm_t a);
// GF(p751^2) addition, c = a+b in GF(p751^2)
extern void fp2add751(const f2elm_t a, const f2elm_t b, f2elm_t c);
// GF(p751^2) subtraction, c = a-b in GF(p751^2)
extern void fp2sub751(const f2elm_t a, const f2elm_t b, f2elm_t c);
// GF(p751^2) division by two, c = a/2 in GF(p751^2)
static void fp2div2_751(const f2elm_t a, f2elm_t c);
// Modular correction, a = a in GF(p751^2)
static void fp2correction751(f2elm_t a);
// GF(p751^2) squaring using Montgomery arithmetic, c = a^2 in GF(p751^2)
static void fp2sqr751_mont(const f2elm_t a, f2elm_t c);
// GF(p751^2) multiplication using Montgomery arithmetic, c = a*b in GF(p751^2)
static void fp2mul751_mont(const f2elm_t a, const f2elm_t b, f2elm_t c);
// Conversion of a GF(p751^2) element to Montgomery representation
static void to_fp2mont(const f2elm_t a, f2elm_t mc);
// Conversion of a GF(p751^2) element from Montgomery representation to standard representation
static void from_fp2mont(const f2elm_t ma, f2elm_t c);
// GF(p751^2) inversion using Montgomery arithmetic, a = (a0-i*a1)/(a0^2+a1^2)
static void fp2inv751_mont(f2elm_t a);
// GF(p751^2) inversion, a = (a0-i*a1)/(a0^2+a1^2), GF(p751) inversion done using the binary GCD
static void fp2inv751_mont_bingcd(f2elm_t a);
// n-way Montgomery inversion
static void mont_n_way_inv(const f2elm_t *vec, const int n, f2elm_t *out);
/************ Elliptic curve and isogeny functions *************/
// Computes the j-invariant of a Montgomery curve with projective constant.
static void j_inv(const f2elm_t A, const f2elm_t C, f2elm_t jinv);
// Simultaneous doubling and differential addition.
static void xDBLADD(point_proj_t P, point_proj_t Q, const f2elm_t xPQ, const f2elm_t A24);
// Doubling of a Montgomery point in projective coordinates (X:Z).
static void xDBL(const point_proj_t P, point_proj_t Q, const f2elm_t A24plus, const f2elm_t C24);
// Computes [2^e](X:Z) on Montgomery curve with projective constant via e repeated doublings.
static void xDBLe(const point_proj_t P, point_proj_t Q, const f2elm_t A24plus, const f2elm_t C24, const int e);
// Differential addition.
static void xADD(point_proj_t P, const point_proj_t Q, const f2elm_t xPQ);
// Computes the corresponding 4-isogeny of a projective Montgomery point (X4:Z4) of order 4.
static void get_4_isog(const point_proj_t P, f2elm_t A24plus, f2elm_t C24, f2elm_t *coeff);
// Evaluates the isogeny at the point (X:Z) in the domain of the isogeny.
static void eval_4_isog(point_proj_t P, f2elm_t *coeff);
// Tripling of a Montgomery point in projective coordinates (X:Z).
static void xTPL(const point_proj_t P, point_proj_t Q, const f2elm_t A24minus, const f2elm_t A24plus);
// Computes [3^e](X:Z) on Montgomery curve with projective constant via e repeated triplings.
static void xTPLe(const point_proj_t P, point_proj_t Q, const f2elm_t A24minus, const f2elm_t A24plus, const int e);
// Computes the corresponding 3-isogeny of a projective Montgomery point (X3:Z3) of order 3.
static void get_3_isog(const point_proj_t P, f2elm_t A24minus, f2elm_t A24plus, f2elm_t *coeff);
// Computes the 3-isogeny R=phi(X:Z), given projective point (X3:Z3) of order 3 on a Montgomery curve and a point P with coefficients given in coeff.
static void eval_3_isog(point_proj_t Q, const f2elm_t *coeff);
// 3-way simultaneous inversion
static void inv_3_way(f2elm_t z1, f2elm_t z2, f2elm_t z3);
// Given the x-coordinates of P, Q, and R, returns the value A corresponding to the Montgomery curve E_A: y^2=x^3+A*x^2+x such that R=Q-P on E_A.
static void get_A(const f2elm_t xP, const f2elm_t xQ, const f2elm_t xR, f2elm_t A);
#endif

View File

@ -140,7 +140,7 @@ static void fp2correction(f2elm_t a) { // Modular correction, a = a in GF(p^2).
__inline static void mp_addfast(const digit_t *a, const digit_t *b, digit_t *c) { // Multiprecision addition, c = a+b.
#if USE_SIKE_ASM
mp_add_asm(a, b, c);
#else
#else
mp_add(a, b, c, NWORDS_FIELD);
#endif
}