mirror of
https://github.com/open-quantum-safe/liboqs.git
synced 2025-11-22 00:09:23 -05:00
make prettyprint
This commit is contained in:
parent
1695d0fbe4
commit
980d78d66a
@ -12,8 +12,8 @@ extern const uint64_t p503p1[NWORDS_FIELD];
|
||||
extern const uint64_t p503x2[NWORDS_FIELD];
|
||||
|
||||
__inline void oqs_kex_sidh_msr_fpadd503(const digit_t *a, const digit_t *b, digit_t *c) { // Modular addition, c = a+b mod p503.
|
||||
// Inputs: a, b in [0, 2*p503-1]
|
||||
// Output: c in [0, 2*p503-1]
|
||||
// Inputs: a, b in [0, 2*p503-1]
|
||||
// Output: c in [0, 2*p503-1]
|
||||
|
||||
#if (OS_TARGET == OS_WIN)
|
||||
unsigned int i, carry = 0;
|
||||
@ -42,8 +42,8 @@ __inline void oqs_kex_sidh_msr_fpadd503(const digit_t *a, const digit_t *b, digi
|
||||
}
|
||||
|
||||
__inline void oqs_kex_sidh_msr_fpsub503(const digit_t *a, const digit_t *b, digit_t *c) { // Modular subtraction, c = a-b mod p503.
|
||||
// Inputs: a, b in [0, 2*p503-1]
|
||||
// Output: c in [0, 2*p503-1]
|
||||
// Inputs: a, b in [0, 2*p503-1]
|
||||
// Output: c in [0, 2*p503-1]
|
||||
|
||||
#if (OS_TARGET == OS_WIN)
|
||||
unsigned int i, borrow = 0;
|
||||
@ -67,7 +67,7 @@ __inline void oqs_kex_sidh_msr_fpsub503(const digit_t *a, const digit_t *b, digi
|
||||
}
|
||||
|
||||
__inline void oqs_kex_sidh_msr_fpneg503(digit_t *a) { // Modular negation, a = -a mod p503.
|
||||
// Input/output: a in [0, 2*p503-1]
|
||||
// Input/output: a in [0, 2*p503-1]
|
||||
unsigned int i, borrow = 0;
|
||||
|
||||
for (i = 0; i < NWORDS_FIELD; i++) {
|
||||
|
||||
@ -38,8 +38,8 @@ digit_t mp_sub503x2_asm(const digit_t *a, const digit_t *b, digit_t *c) { // Mul
|
||||
}
|
||||
|
||||
__inline void oqs_kex_sidh_msr_fpadd503(const digit_t *a, const digit_t *b, digit_t *c) { // Modular addition, c = a+b mod p503.
|
||||
// Inputs: a, b in [0, 2*p503-1]
|
||||
// Output: c in [0, 2*p503-1]
|
||||
// Inputs: a, b in [0, 2*p503-1]
|
||||
// Output: c in [0, 2*p503-1]
|
||||
unsigned int i, carry = 0;
|
||||
digit_t mask;
|
||||
|
||||
@ -60,8 +60,8 @@ __inline void oqs_kex_sidh_msr_fpadd503(const digit_t *a, const digit_t *b, digi
|
||||
}
|
||||
|
||||
__inline void oqs_kex_sidh_msr_fpsub503(const digit_t *a, const digit_t *b, digit_t *c) { // Modular subtraction, c = a-b mod p503.
|
||||
// Inputs: a, b in [0, 2*p503-1]
|
||||
// Output: c in [0, 2*p503-1]
|
||||
// Inputs: a, b in [0, 2*p503-1]
|
||||
// Output: c in [0, 2*p503-1]
|
||||
unsigned int i, borrow = 0;
|
||||
digit_t mask;
|
||||
|
||||
@ -77,7 +77,7 @@ __inline void oqs_kex_sidh_msr_fpsub503(const digit_t *a, const digit_t *b, digi
|
||||
}
|
||||
|
||||
__inline void oqs_kex_sidh_msr_fpneg503(digit_t *a) { // Modular negation, a = -a mod p503.
|
||||
// Input/output: a in [0, 2*p503-1]
|
||||
// Input/output: a in [0, 2*p503-1]
|
||||
unsigned int i, borrow = 0;
|
||||
|
||||
for (i = 0; i < NWORDS_FIELD; i++) {
|
||||
|
||||
@ -7,7 +7,6 @@
|
||||
#include "P503_api.h"
|
||||
#include "P503_internal.h"
|
||||
|
||||
|
||||
// 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).
|
||||
@ -20,105 +19,104 @@
|
||||
// Curve isogeny system "SIDHp503". Base curve: Montgomery curve By^2 = Cx^3 + Ax^2 + Cx defined over GF(p503^2), where A=0, 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 };
|
||||
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 };
|
||||
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 };
|
||||
static const uint64_t Bob_order[NWORDS64_ORDER] = {0xC216F6888479E82B, 0xE6FDB21EDF9F6BC4, 0x1171AF769DE93406, 0x1019BD5060478798};
|
||||
// Alice's generator values {XPA0 + XPA1*i, XQA0, XRA0 + XRA1*i} in GF(p503^2), expressed in Montgomery representation
|
||||
static const uint64_t A_gen[5*NWORDS64_FIELD] = { 0xE7EF4AA786D855AF, 0xED5758F03EB34D3B, 0x09AE172535A86AA9, 0x237B9CC07D622723,
|
||||
0xE3A284CBA4E7932D, 0x27481D9176C5E63F, 0x6A323FF55C6E71BF, 0x002ECC31A6FB8773, // XPA0
|
||||
0x64D02E4E90A620B8, 0xDAB8128537D4B9F1, 0x4BADF77B8A228F98, 0x0F5DBDF9D1FB7D1B,
|
||||
0xBEC4DB288E1A0DCC, 0xE76A8665E80675DB, 0x6D6F252E12929463, 0x003188BD1463FACC, // XPA1
|
||||
0xB79D41025DE85D56, 0x0B867DA9DF169686, 0x740E5368021C827D, 0x20615D72157BF25C,
|
||||
0xFF1590013C9B9F5B, 0xC884DCADE8C16CEA, 0xEBD05E53BF724E01, 0x0032FEF8FDA5748C, // XQA0
|
||||
0x12E2E849AA0A8006, 0x41CF47008635A1E8, 0x9CD720A70798AED7, 0x42A820B42FCF04CF,
|
||||
0x7BF9BAD32AAE88B1, 0xF619127A54090BBE, 0x1CB10D8F56408EAA, 0x001D6B54C3C0EDEB, // XRA0
|
||||
0x34DB54931CBAAC36, 0x420A18CB8DD5F0C4, 0x32008C1A48C0F44D, 0x3B3BA772B1CFD44D,
|
||||
0xA74B058FDAF13515, 0x095FC9CA7EEC17B4, 0x448E829D28F120F8, 0x00261EC3ED16A489 }; // XRA1
|
||||
static const uint64_t A_gen[5 * NWORDS64_FIELD] = {0xE7EF4AA786D855AF, 0xED5758F03EB34D3B, 0x09AE172535A86AA9, 0x237B9CC07D622723,
|
||||
0xE3A284CBA4E7932D, 0x27481D9176C5E63F, 0x6A323FF55C6E71BF, 0x002ECC31A6FB8773, // XPA0
|
||||
0x64D02E4E90A620B8, 0xDAB8128537D4B9F1, 0x4BADF77B8A228F98, 0x0F5DBDF9D1FB7D1B,
|
||||
0xBEC4DB288E1A0DCC, 0xE76A8665E80675DB, 0x6D6F252E12929463, 0x003188BD1463FACC, // XPA1
|
||||
0xB79D41025DE85D56, 0x0B867DA9DF169686, 0x740E5368021C827D, 0x20615D72157BF25C,
|
||||
0xFF1590013C9B9F5B, 0xC884DCADE8C16CEA, 0xEBD05E53BF724E01, 0x0032FEF8FDA5748C, // XQA0
|
||||
0x12E2E849AA0A8006, 0x41CF47008635A1E8, 0x9CD720A70798AED7, 0x42A820B42FCF04CF,
|
||||
0x7BF9BAD32AAE88B1, 0xF619127A54090BBE, 0x1CB10D8F56408EAA, 0x001D6B54C3C0EDEB, // XRA0
|
||||
0x34DB54931CBAAC36, 0x420A18CB8DD5F0C4, 0x32008C1A48C0F44D, 0x3B3BA772B1CFD44D,
|
||||
0xA74B058FDAF13515, 0x095FC9CA7EEC17B4, 0x448E829D28F120F8, 0x00261EC3ED16A489}; // XRA1
|
||||
// Bob's generator values {XPB0 + XPB1*i, XQB0, XRB0 + XRB1*i} in GF(p503^2), expressed in Montgomery representation
|
||||
static const uint64_t B_gen[5*NWORDS64_FIELD] = { 0x7EDE37F4FA0BC727, 0xF7F8EC5C8598941C, 0xD15519B516B5F5C8, 0xF6D5AC9B87A36282,
|
||||
0x7B19F105B30E952E, 0x13BD8B2025B4EBEE, 0x7B96D27F4EC579A2, 0x00140850CAB7E5DE, // XPB0
|
||||
0x7764909DAE7B7B2D, 0x578ABB16284911AB, 0x76E2BFD146A6BF4D, 0x4824044B23AA02F0,
|
||||
0x1105048912A321F3, 0xB8A2E482CF0F10C1, 0x42FF7D0BE2152085, 0x0018E599C5223352, // XPB1
|
||||
0x4256C520FB388820, 0x744FD7C3BAAF0A13, 0x4B6A2DDDB12CBCB8, 0xE46826E27F427DF8,
|
||||
0xFE4A663CD505A61B, 0xD6B3A1BAF025C695, 0x7C3BB62B8FCC00BD, 0x003AFDDE4A35746C, // XQB0
|
||||
0x75601CD1E6C0DFCB, 0x1A9007239B58F93E, 0xC1F1BE80C62107AC, 0x7F513B898F29FF08,
|
||||
0xEA0BEDFF43E1F7B2, 0x2C6D94018CBAE6D0, 0x3A430D31BCD84672, 0x000D26892ECCFE83, // XRB0
|
||||
0x1119D62AEA3007A1, 0xE3702AA4E04BAE1B, 0x9AB96F7D59F990E7, 0xF58440E8B43319C0,
|
||||
0xAF8134BEE1489775, 0xE7F7774E905192AA, 0xF54AE09308E98039, 0x001EF7A041A86112 }; // XRB1
|
||||
static const uint64_t B_gen[5 * NWORDS64_FIELD] = {0x7EDE37F4FA0BC727, 0xF7F8EC5C8598941C, 0xD15519B516B5F5C8, 0xF6D5AC9B87A36282,
|
||||
0x7B19F105B30E952E, 0x13BD8B2025B4EBEE, 0x7B96D27F4EC579A2, 0x00140850CAB7E5DE, // XPB0
|
||||
0x7764909DAE7B7B2D, 0x578ABB16284911AB, 0x76E2BFD146A6BF4D, 0x4824044B23AA02F0,
|
||||
0x1105048912A321F3, 0xB8A2E482CF0F10C1, 0x42FF7D0BE2152085, 0x0018E599C5223352, // XPB1
|
||||
0x4256C520FB388820, 0x744FD7C3BAAF0A13, 0x4B6A2DDDB12CBCB8, 0xE46826E27F427DF8,
|
||||
0xFE4A663CD505A61B, 0xD6B3A1BAF025C695, 0x7C3BB62B8FCC00BD, 0x003AFDDE4A35746C, // XQB0
|
||||
0x75601CD1E6C0DFCB, 0x1A9007239B58F93E, 0xC1F1BE80C62107AC, 0x7F513B898F29FF08,
|
||||
0xEA0BEDFF43E1F7B2, 0x2C6D94018CBAE6D0, 0x3A430D31BCD84672, 0x000D26892ECCFE83, // XRB0
|
||||
0x1119D62AEA3007A1, 0xE3702AA4E04BAE1B, 0x9AB96F7D59F990E7, 0xF58440E8B43319C0,
|
||||
0xAF8134BEE1489775, 0xE7F7774E905192AA, 0xF54AE09308E98039, 0x001EF7A041A86112}; // 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 };
|
||||
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 };
|
||||
static const uint64_t Montgomery_one[NWORDS64_FIELD] = {0x00000000000003F9, 0x0000000000000000, 0x0000000000000000, 0xB400000000000000,
|
||||
0x63CB1A6EA6DED2B4, 0x51689D8D667EB37D, 0x8ACD77C71AB24142, 0x0026FBAEC60F5953};
|
||||
// Value (2^256)^2 mod 3^159
|
||||
static const uint64_t Montgomery_Rprime[NWORDS64_ORDER] = { 0x0C2615CA3C5BAA99, 0x5A4FF3072AB6AA6A, 0xA6AFD4B039AD6AA2, 0x010DA06A26DD05CB };
|
||||
static const uint64_t Montgomery_Rprime[NWORDS64_ORDER] = {0x0C2615CA3C5BAA99, 0x5A4FF3072AB6AA6A, 0xA6AFD4B039AD6AA2, 0x010DA06A26DD05CB};
|
||||
// Value -(3^159)^-1 mod 2^256
|
||||
static const uint64_t Montgomery_rprime[NWORDS64_ORDER] = { 0x49C8A87190C0697D, 0x2EB7968EA0F0A558, 0x944257B696777FA2, 0xBAA4DDCD6139D2B3 };
|
||||
static const uint64_t Montgomery_rprime[NWORDS64_ORDER] = {0x49C8A87190C0697D, 0x2EB7968EA0F0A558, 0x944257B696777FA2, 0xBAA4DDCD6139D2B3};
|
||||
// Value order_Bob/3 mod p503
|
||||
static const uint64_t Border_div3[NWORDS_ORDER] = { 0xEB5CFCD82C28A2B9, 0x4CFF3B5F9FDFCE96, 0xB07B3A7CDF4DBC02, 0x055DE9C5756D2D32 };
|
||||
|
||||
static const uint64_t Border_div3[NWORDS_ORDER] = {0xEB5CFCD82C28A2B9, 0x4CFF3B5F9FDFCE96, 0xB07B3A7CDF4DBC02, 0x055DE9C5756D2D32};
|
||||
|
||||
// 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_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 };
|
||||
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 oqs_kex_sidh_msr_fpadd503
|
||||
#define fpsub oqs_kex_sidh_msr_fpsub503
|
||||
#define fpneg oqs_kex_sidh_msr_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 oqs_kex_sidh_msr_fp2add503
|
||||
#define fp2sub oqs_kex_sidh_msr_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 mp_add503_asm
|
||||
#define mp_addx2_asm mp_add503x2_asm
|
||||
#define mp_subx2_asm mp_sub503x2_asm
|
||||
#define crypto_kem_keypair crypto_kem_keypair_SIKEp503
|
||||
#define crypto_kem_enc crypto_kem_enc_SIKEp503
|
||||
#define crypto_kem_dec crypto_kem_dec_SIKEp503
|
||||
#define random_mod_order_A random_mod_order_A_SIDHp503
|
||||
#define random_mod_order_B random_mod_order_B_SIDHp503
|
||||
#define EphemeralKeyGeneration_A EphemeralKeyGeneration_A_SIDHp503
|
||||
#define EphemeralKeyGeneration_B EphemeralKeyGeneration_B_SIDHp503
|
||||
#define EphemeralSecretAgreement_A EphemeralSecretAgreement_A_SIDHp503
|
||||
#define EphemeralSecretAgreement_B EphemeralSecretAgreement_B_SIDHp503
|
||||
#define fpcopy fpcopy503
|
||||
#define fpzero fpzero503
|
||||
#define fpadd oqs_kex_sidh_msr_fpadd503
|
||||
#define fpsub oqs_kex_sidh_msr_fpsub503
|
||||
#define fpneg oqs_kex_sidh_msr_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 oqs_kex_sidh_msr_fp2add503
|
||||
#define fp2sub oqs_kex_sidh_msr_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 mp_add503_asm
|
||||
#define mp_addx2_asm mp_add503x2_asm
|
||||
#define mp_subx2_asm mp_sub503x2_asm
|
||||
#define crypto_kem_keypair crypto_kem_keypair_SIKEp503
|
||||
#define crypto_kem_enc crypto_kem_enc_SIKEp503
|
||||
#define crypto_kem_dec crypto_kem_dec_SIKEp503
|
||||
#define random_mod_order_A random_mod_order_A_SIDHp503
|
||||
#define random_mod_order_B random_mod_order_B_SIDHp503
|
||||
#define EphemeralKeyGeneration_A EphemeralKeyGeneration_A_SIDHp503
|
||||
#define EphemeralKeyGeneration_B EphemeralKeyGeneration_B_SIDHp503
|
||||
#define EphemeralSecretAgreement_A EphemeralSecretAgreement_A_SIDHp503
|
||||
#define EphemeralSecretAgreement_B EphemeralSecretAgreement_B_SIDHp503
|
||||
|
||||
#if defined(X86_64)
|
||||
#include "AMD64/fp_x64.c"
|
||||
|
||||
@ -9,13 +9,12 @@
|
||||
|
||||
#include <oqs/rand.h>
|
||||
|
||||
|
||||
/*********************** Key encapsulation mechanism API ***********************/
|
||||
|
||||
#define CRYPTO_SECRETKEYBYTES 434 // MSG_BYTES + SECRETKEY_B_BYTES + CRYPTO_PUBLICKEYBYTES bytes
|
||||
#define CRYPTO_PUBLICKEYBYTES 378
|
||||
#define CRYPTO_BYTES 16
|
||||
#define CRYPTO_CIPHERTEXTBYTES 402 // CRYPTO_PUBLICKEYBYTES + MSG_BYTES bytes
|
||||
#define CRYPTO_SECRETKEYBYTES 434 // MSG_BYTES + SECRETKEY_B_BYTES + CRYPTO_PUBLICKEYBYTES bytes
|
||||
#define CRYPTO_PUBLICKEYBYTES 378
|
||||
#define CRYPTO_BYTES 16
|
||||
#define CRYPTO_CIPHERTEXTBYTES 402 // CRYPTO_PUBLICKEYBYTES + MSG_BYTES bytes
|
||||
|
||||
// Algorithm name
|
||||
#define CRYPTO_ALGNAME "SIKEp503"
|
||||
@ -38,7 +37,6 @@ int crypto_kem_enc_SIKEp503(unsigned char *ct, unsigned char *ss, const unsigned
|
||||
// Outputs: shared secret ss (CRYPTO_BYTES = 16 bytes)
|
||||
int crypto_kem_dec_SIKEp503(unsigned char *ss, const unsigned char *ct, const unsigned char *sk, OQS_RAND *rand);
|
||||
|
||||
|
||||
// Encoding of keys for KEM-based isogeny system "SIKEp503" (wire format):
|
||||
// ----------------------------------------------------------------------
|
||||
// Elements over GF(p503) are encoded in 63 octets in little endian format (i.e., the least significant octet is located in the lowest memory address).
|
||||
@ -50,12 +48,11 @@ int crypto_kem_dec_SIKEp503(unsigned char *ss, const unsigned char *ct, const un
|
||||
// Ciphertexts ct consist of the concatenation of a public key value and a 24-byte value. In the SIKE API, ct is encoded in 378 + 24 = 402 octets.
|
||||
// Shared keys ss consist of a value of 16 octets.
|
||||
|
||||
|
||||
/*********************** Ephemeral key exchange API ***********************/
|
||||
|
||||
#define SIDH_SECRETKEYBYTES 32
|
||||
#define SIDH_PUBLICKEYBYTES 378
|
||||
#define SIDH_BYTES 126
|
||||
#define SIDH_SECRETKEYBYTES 32
|
||||
#define SIDH_PUBLICKEYBYTES 378
|
||||
#define SIDH_BYTES 126
|
||||
|
||||
// SECURITY NOTE: SIDH supports ephemeral Diffie-Hellman key exchange. It is NOT secure to use it with static keys.
|
||||
// See "On the Security of Supersingular Isogeny Cryptosystems", S.D. Galbraith, C. Petit, B. Shani and Y.B. Ti, in ASIACRYPT 2016, 2016.
|
||||
@ -63,37 +60,36 @@ int crypto_kem_dec_SIKEp503(unsigned char *ss, const unsigned char *ct, const un
|
||||
|
||||
// Generation of Alice's secret key
|
||||
// Outputs random value in [0, 2^250 - 1] to be used as Alice's private key
|
||||
void random_mod_order_A_SIDHp503(unsigned char* random_digits, OQS_RAND* rand);
|
||||
void random_mod_order_A_SIDHp503(unsigned char *random_digits, OQS_RAND *rand);
|
||||
|
||||
// Generation of Bob's secret key
|
||||
// Outputs random value in [0, 2^Floor(Log(2,3^159)) - 1] to be used as Bob's private key
|
||||
void random_mod_order_B_SIDHp503(unsigned char* random_digits, OQS_RAND* rand);
|
||||
void random_mod_order_B_SIDHp503(unsigned char *random_digits, OQS_RAND *rand);
|
||||
|
||||
// Alice's ephemeral public key generation
|
||||
// Input: a private key PrivateKeyA in the range [0, 2^250 - 1], stored in 32 bytes.
|
||||
// Output: the public key PublicKeyA consisting of 3 GF(p503^2) elements encoded in 378 bytes.
|
||||
int EphemeralKeyGeneration_A_SIDHp503(const unsigned char* PrivateKeyA, unsigned char* PublicKeyA, OQS_RAND* rand);
|
||||
int EphemeralKeyGeneration_A_SIDHp503(const unsigned char *PrivateKeyA, unsigned char *PublicKeyA, OQS_RAND *rand);
|
||||
|
||||
// Bob's ephemeral key-pair generation
|
||||
// It produces a private key PrivateKeyB and computes the public key PublicKeyB.
|
||||
// The private key is an integer in the range [0, 2^Floor(Log(2,3^159)) - 1], stored in 32 bytes.
|
||||
// The public key consists of 3 GF(p503^2) elements encoded in 378 bytes.
|
||||
int EphemeralKeyGeneration_B_SIDHp503(const unsigned char* PrivateKeyB, unsigned char* PublicKeyB, OQS_RAND* rand);
|
||||
int EphemeralKeyGeneration_B_SIDHp503(const unsigned char *PrivateKeyB, unsigned char *PublicKeyB, OQS_RAND *rand);
|
||||
|
||||
// Alice's ephemeral shared secret computation
|
||||
// It produces a shared secret key SharedSecretA using her secret key PrivateKeyA and Bob's public key PublicKeyB
|
||||
// Inputs: Alice's PrivateKeyA is an integer in the range [0, 2^250 - 1], stored in 32 bytes.
|
||||
// Bob's PublicKeyB consists of 3 GF(p503^2) elements encoded in 378 bytes.
|
||||
// Output: a shared secret SharedSecretA that consists of one element in GF(p503^2) encoded in 126 bytes.
|
||||
int EphemeralSecretAgreement_A_SIDHp503(const unsigned char* PrivateKeyA, const unsigned char* PublicKeyB, unsigned char* SharedSecretA);
|
||||
int EphemeralSecretAgreement_A_SIDHp503(const unsigned char *PrivateKeyA, const unsigned char *PublicKeyB, unsigned char *SharedSecretA);
|
||||
|
||||
// Bob's ephemeral shared secret computation
|
||||
// It produces a shared secret key SharedSecretB using his secret key PrivateKeyB and Alice's public key PublicKeyA
|
||||
// Inputs: Bob's PrivateKeyB is an integer in the range [0, 2^Floor(Log(2,3^159)) - 1], stored in 32 bytes.
|
||||
// Alice's PublicKeyA consists of 3 GF(p503^2) elements encoded in 378 bytes.
|
||||
// Output: a shared secret SharedSecretB that consists of one element in GF(p503^2) encoded in 126 bytes.
|
||||
int EphemeralSecretAgreement_B_SIDHp503(const unsigned char* PrivateKeyB, const unsigned char* PublicKeyA, unsigned char* SharedSecretB);
|
||||
|
||||
int EphemeralSecretAgreement_B_SIDHp503(const unsigned char *PrivateKeyB, const unsigned char *PublicKeyA, unsigned char *SharedSecretB);
|
||||
|
||||
// Encoding of keys for KEX-based isogeny system "SIDHp503" (wire format):
|
||||
// ----------------------------------------------------------------------
|
||||
@ -105,5 +101,4 @@ int EphemeralSecretAgreement_B_SIDHp503(const unsigned char* PrivateKeyB, const
|
||||
// Public keys PublicKeyA and PublicKeyB consist of 3 elements in GF(p503^2). In the SIDH API, they are encoded in 378 octets.
|
||||
// Shared keys SharedSecretA and SharedSecretB consist of one element in GF(p503^2). In the SIDH API, they are encoded in 126 octets.
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@ -9,155 +9,153 @@
|
||||
|
||||
#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
|
||||
#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
|
||||
#define NWORDS_FIELD 16
|
||||
#define p503_ZERO_WORDS 7
|
||||
#elif (TARGET == TARGET_ARM)
|
||||
#define NWORDS_FIELD 16
|
||||
#define p503_ZERO_WORDS 7
|
||||
#define NWORDS_FIELD 16
|
||||
#define p503_ZERO_WORDS 7
|
||||
#elif (TARGET == TARGET_ARM64)
|
||||
#define NWORDS_FIELD 8
|
||||
#define p503_ZERO_WORDS 3
|
||||
#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 MAXWORDS_ORDER ((MAXBITS_ORDER+RADIX-1)/RADIX) // Max. number of words to represent elements in [1, oA-1] or [1, oB].
|
||||
#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 0
|
||||
#define PARAM_C 1
|
||||
#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 MAXWORDS_ORDER ((MAXBITS_ORDER + RADIX - 1) / RADIX) // Max. number of words to represent elements in [1, oA-1] or [1, oB].
|
||||
#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 0
|
||||
#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 + 7) / 8
|
||||
#define FP2_ENCODED_BYTES 2*((NBITS_FIELD + 7) / 8)
|
||||
|
||||
#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 + 7) / 8
|
||||
#define FP2_ENCODED_BYTES 2 * ((NBITS_FIELD + 7) / 8)
|
||||
|
||||
// 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 (512-bit max.)
|
||||
typedef felm_t f2elm_t[2]; // Datatype for representing quadratic extension field elements GF(p503^2)
|
||||
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 (512-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 struct {
|
||||
f2elm_t X;
|
||||
f2elm_t Z;
|
||||
} point_proj; // Point representation in projective XZ Montgomery coordinates.
|
||||
typedef point_proj point_proj_t[1];
|
||||
|
||||
|
||||
|
||||
/**************** 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);
|
||||
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);
|
||||
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);
|
||||
static void mp_add503_asm(const digit_t* a, const digit_t* b, digit_t* c);
|
||||
static void mp_add503(const digit_t *a, const digit_t *b, digit_t *c);
|
||||
static void mp_add503_asm(const digit_t *a, const digit_t *b, digit_t *c);
|
||||
//void mp_addmask503_asm(const digit_t* a, const digit_t mask, digit_t* c);
|
||||
|
||||
// 2x503-bit multiprecision addition, c = a+b
|
||||
static void mp_add503x2(const digit_t* a, const digit_t* b, digit_t* c);
|
||||
static void mp_add503x2_asm(const digit_t* a, const digit_t* b, digit_t* c);
|
||||
static void mp_add503x2(const digit_t *a, const digit_t *b, digit_t *c);
|
||||
static void mp_add503x2_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);
|
||||
static digit_t mp_sub503x2_asm(const digit_t* a, const digit_t* b, digit_t* c);
|
||||
static unsigned int mp_sub(const digit_t *a, const digit_t *b, digit_t *c, const unsigned int nwords);
|
||||
static digit_t mp_sub503x2_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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
static void fpcopy503(const digit_t *a, digit_t *c);
|
||||
|
||||
// Zeroing a field element, a = 0
|
||||
static void fpzero503(digit_t* a);
|
||||
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);
|
||||
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 fpadd503_asm(const digit_t* a, const digit_t* b, digit_t* c);
|
||||
extern void fpadd503(const digit_t *a, const digit_t *b, digit_t *c);
|
||||
extern void fpadd503_asm(const digit_t *a, const digit_t *b, 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 fpsub503_asm(const digit_t* a, const digit_t* b, digit_t* c);
|
||||
extern void fpsub503(const digit_t *a, const digit_t *b, digit_t *c);
|
||||
extern void fpsub503_asm(const digit_t *a, const digit_t *b, digit_t *c);
|
||||
|
||||
// Modular negation, a = -a mod p503
|
||||
extern void fpneg503(digit_t* a);
|
||||
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);
|
||||
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);
|
||||
static void fpcorrection503(digit_t *a);
|
||||
|
||||
// 503-bit Montgomery reduction, c = a mod p
|
||||
static void rdc_mont(const digit_t* a, digit_t* c);
|
||||
static void rdc_mont(const digit_t *a, digit_t *c);
|
||||
|
||||
// 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);
|
||||
static void mul503_asm(const digit_t* a, const digit_t* b, digit_t* c);
|
||||
static void rdc503_asm(const digit_t* ma, digit_t* mc);
|
||||
static void fpmul503_mont(const digit_t *a, const digit_t *b, digit_t *c);
|
||||
static void mul503_asm(const digit_t *a, const digit_t *b, digit_t *c);
|
||||
static void rdc503_asm(const digit_t *ma, digit_t *mc);
|
||||
|
||||
// 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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
static void fpinv503_chain_mont(digit_t *a);
|
||||
|
||||
/************ GF(p^2) arithmetic functions *************/
|
||||
|
||||
@ -201,7 +199,7 @@ static void fp2inv503_mont(f2elm_t a);
|
||||
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);
|
||||
static void mont_n_way_inv(const f2elm_t *vec, const int n, f2elm_t *out);
|
||||
|
||||
/************ Elliptic curve and isogeny functions *************/
|
||||
|
||||
@ -221,10 +219,10 @@ static void xDBLe(const point_proj_t P, point_proj_t Q, const f2elm_t A24plus, c
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
@ -233,10 +231,10 @@ static void xTPL(const point_proj_t P, point_proj_t Q, const f2elm_t A24minus, c
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
@ -244,5 +242,4 @@ 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
|
||||
|
||||
@ -12,8 +12,8 @@ extern const uint64_t p503p1[NWORDS_FIELD];
|
||||
extern const uint64_t p503x2[NWORDS_FIELD];
|
||||
|
||||
__inline void oqs_kex_sidh_msr_fpadd503(const digit_t *a, const digit_t *b, digit_t *c) { // Modular addition, c = a+b mod p503.
|
||||
// Inputs: a, b in [0, 2*p503-1]
|
||||
// Output: c in [0, 2*p503-1]
|
||||
// Inputs: a, b in [0, 2*p503-1]
|
||||
// Output: c in [0, 2*p503-1]
|
||||
unsigned int i, carry = 0;
|
||||
digit_t mask;
|
||||
|
||||
@ -34,8 +34,8 @@ __inline void oqs_kex_sidh_msr_fpadd503(const digit_t *a, const digit_t *b, digi
|
||||
}
|
||||
|
||||
__inline void oqs_kex_sidh_msr_fpsub503(const digit_t *a, const digit_t *b, digit_t *c) { // Modular subtraction, c = a-b mod p503.
|
||||
// Inputs: a, b in [0, 2*p503-1]
|
||||
// Output: c in [0, 2*p503-1]
|
||||
// Inputs: a, b in [0, 2*p503-1]
|
||||
// Output: c in [0, 2*p503-1]
|
||||
unsigned int i, borrow = 0;
|
||||
digit_t mask;
|
||||
|
||||
@ -51,7 +51,7 @@ __inline void oqs_kex_sidh_msr_fpsub503(const digit_t *a, const digit_t *b, digi
|
||||
}
|
||||
|
||||
__inline void oqs_kex_sidh_msr_fpneg503(digit_t *a) { // Modular negation, a = -a mod p503.
|
||||
// Input/output: a in [0, 2*p503-1]
|
||||
// Input/output: a in [0, 2*p503-1]
|
||||
unsigned int i, borrow = 0;
|
||||
|
||||
for (i = 0; i < NWORDS_FIELD; i++) {
|
||||
|
||||
@ -19,110 +19,109 @@
|
||||
// Curve isogeny system "SIDHp751". Base curve: Montgomery curve By^2 = Cx^3 + Ax^2 + Cx defined over GF(p751^2), where A=0, 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 };
|
||||
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 };
|
||||
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 };
|
||||
static const uint64_t Bob_order[NWORDS64_ORDER] = {0xC968549F878A8EEB, 0x59B1A13F7CC76E3E, 0xE9867D6EBE876DA9, 0x2B5045CB25748084, 0x2909F97BADC66856, 0x06FE5D541F71C0E1};
|
||||
// Alice's generator values {XPA0 + XPA1*i, XQA0, XRA0 + XRA1*i} in GF(p751^2), expressed in Montgomery representation
|
||||
static const uint64_t A_gen[5 * NWORDS64_FIELD] = { 0xC2FC08CEAB50AD8B, 0x1D7D710F55E457B1, 0xE8738D92953DCD6E, 0xBAA7EBEE8A3418AA, 0xC9A288345F03F46F, 0xC8D18D167CFE2616,
|
||||
0x02043761F6B1C045, 0xAA1975E13180E7E9, 0x9E13D3FDC6690DE6, 0x3A024640A3A3BB4F, 0x4E5AD44E6ACBBDAE, 0x0000544BEB561DAD, // XPA0
|
||||
0xE6CC41D21582E411, 0x07C2ECB7C5DF400A, 0xE8E34B521432AEC4, 0x50761E2AB085167D, 0x032CFBCAA6094B3C, 0x6C522F5FDF9DDD71,
|
||||
0x1319217DC3A1887D, 0xDC4FB25803353A86, 0x362C8D7B63A6AB09, 0x39DCDFBCE47EA488, 0x4C27C99A2C28D409, 0x00003CB0075527C4, // XPA1
|
||||
0xD56FE52627914862, 0x1FAD60DC96B5BAEA, 0x01E137D0BF07AB91, 0x404D3E9252161964, 0x3C5385E4CD09A337, 0x4476426769E4AF73,
|
||||
0x9790C6DB989DFE33, 0xE06E1C04D2AA8B5E, 0x38C08185EDEA73B9, 0xAA41F678A4396CA6, 0x92B9259B2229E9A0, 0x00002F9326818BE0, // XQA0
|
||||
0x0BB84441DFFD19B3, 0x84B4DEA99B48C18E, 0x692DE648AD313805, 0xE6D72761B6DFAEE0, 0x223975C672C3058D, 0xA0FDE0C3CBA26FDC,
|
||||
0xA5326132A922A3CA, 0xCA5E7F5D5EA96FA4, 0x127C7EFE33FFA8C6, 0x4749B1567E2A23C4, 0x2B7DF5B4AF413BFA, 0x0000656595B9623C, // XRA0
|
||||
0xED78C17F1EC71BE8, 0xF824D6DF753859B1, 0x33A10839B2A8529F, 0xFC03E9E25FDEA796, 0xC4708A8054DF1762, 0x4034F2EC034C6467,
|
||||
0xABFB70FBF06ECC79, 0xDABE96636EC108B7, 0x49CBCFB090605FD3, 0x20B89711819A45A7, 0xFB8E1590B2B0F63E, 0x0000556A5F964AB2 }; // XRA1
|
||||
static const uint64_t A_gen[5 * NWORDS64_FIELD] = {0xC2FC08CEAB50AD8B, 0x1D7D710F55E457B1, 0xE8738D92953DCD6E, 0xBAA7EBEE8A3418AA, 0xC9A288345F03F46F, 0xC8D18D167CFE2616,
|
||||
0x02043761F6B1C045, 0xAA1975E13180E7E9, 0x9E13D3FDC6690DE6, 0x3A024640A3A3BB4F, 0x4E5AD44E6ACBBDAE, 0x0000544BEB561DAD, // XPA0
|
||||
0xE6CC41D21582E411, 0x07C2ECB7C5DF400A, 0xE8E34B521432AEC4, 0x50761E2AB085167D, 0x032CFBCAA6094B3C, 0x6C522F5FDF9DDD71,
|
||||
0x1319217DC3A1887D, 0xDC4FB25803353A86, 0x362C8D7B63A6AB09, 0x39DCDFBCE47EA488, 0x4C27C99A2C28D409, 0x00003CB0075527C4, // XPA1
|
||||
0xD56FE52627914862, 0x1FAD60DC96B5BAEA, 0x01E137D0BF07AB91, 0x404D3E9252161964, 0x3C5385E4CD09A337, 0x4476426769E4AF73,
|
||||
0x9790C6DB989DFE33, 0xE06E1C04D2AA8B5E, 0x38C08185EDEA73B9, 0xAA41F678A4396CA6, 0x92B9259B2229E9A0, 0x00002F9326818BE0, // XQA0
|
||||
0x0BB84441DFFD19B3, 0x84B4DEA99B48C18E, 0x692DE648AD313805, 0xE6D72761B6DFAEE0, 0x223975C672C3058D, 0xA0FDE0C3CBA26FDC,
|
||||
0xA5326132A922A3CA, 0xCA5E7F5D5EA96FA4, 0x127C7EFE33FFA8C6, 0x4749B1567E2A23C4, 0x2B7DF5B4AF413BFA, 0x0000656595B9623C, // XRA0
|
||||
0xED78C17F1EC71BE8, 0xF824D6DF753859B1, 0x33A10839B2A8529F, 0xFC03E9E25FDEA796, 0xC4708A8054DF1762, 0x4034F2EC034C6467,
|
||||
0xABFB70FBF06ECC79, 0xDABE96636EC108B7, 0x49CBCFB090605FD3, 0x20B89711819A45A7, 0xFB8E1590B2B0F63E, 0x0000556A5F964AB2}; // XRA1
|
||||
// Bob's generator values {XPB0 + XPB1*i, XQB0, XRB0 + XRB1*i} in GF(p751^2), expressed in Montgomery representation
|
||||
static const uint64_t B_gen[5 * NWORDS64_FIELD] = { 0xCFB6D71EF867AB0B, 0x4A5FDD76E9A45C76, 0x38B1EE69194B1F03, 0xF6E7B18A7761F3F0, 0xFCF01A486A52C84C, 0xCBE2F63F5AA75466,
|
||||
0x6487BCE837B5E4D6, 0x7747F5A8C622E9B8, 0x4CBFE1E4EE6AEBBA, 0x8A8616A13FA91512, 0x53DB980E1579E0A5, 0x000058FEBFF3BE69, // XPB0
|
||||
0xA492034E7C075CC3, 0x677BAF00B04AA430, 0x3AAE0C9A755C94C8, 0x1DC4B064E9EBB08B, 0x3684EDD04E826C66, 0x9BAA6CB661F01B22,
|
||||
0x20285A00AD2EFE35, 0xDCE95ABD0497065F, 0x16C7FBB3778E3794, 0x26B3AC29CEF25AAF, 0xFB3C28A31A30AC1D, 0x000046ED190624EE, // XPB1
|
||||
0xF1A8C9ED7B96C4AB, 0x299429DA5178486E, 0xEF4926F20CD5C2F4, 0x683B2E2858B4716A, 0xDDA2FBCC3CAC3EEB, 0xEC055F9F3A600460,
|
||||
0xD5A5A17A58C3848B, 0x4652D836F42EAED5, 0x2F2E71ED78B3A3B3, 0xA771C057180ADD1D, 0xC780A5D2D835F512, 0x0000114EA3B55AC1, // XQB0
|
||||
0x1C0D6733769D0F31, 0xF084C3086E2659D1, 0xE23D5DA27BCBD133, 0xF38EC9A8D5864025, 0x6426DC781B3B645B, 0x4B24E8E3C9FB03EE,
|
||||
0x6432792F9D2CEA30, 0x7CC8E8B1AE76E857, 0x7F32BFB626BB8963, 0xB9F05995B48D7B74, 0x4D71200A7D67E042, 0x0000228457AF0637, // XRB0
|
||||
0x4AE37E7D8F72BD95, 0xDD2D504B3E993488, 0x5D14E7FA1ECB3C3E, 0x127610CEB75D6350, 0x255B4B4CAC446B11, 0x9EA12336C1F70CAF,
|
||||
0x79FA68A2147BC2F8, 0x11E895CFDADBBC49, 0xE4B9D3C4D6356C18, 0x44B25856A67F951C, 0x5851541F61308D0B, 0x00002FFD994F7E4C }; // XRB1
|
||||
static const uint64_t B_gen[5 * NWORDS64_FIELD] = {0xCFB6D71EF867AB0B, 0x4A5FDD76E9A45C76, 0x38B1EE69194B1F03, 0xF6E7B18A7761F3F0, 0xFCF01A486A52C84C, 0xCBE2F63F5AA75466,
|
||||
0x6487BCE837B5E4D6, 0x7747F5A8C622E9B8, 0x4CBFE1E4EE6AEBBA, 0x8A8616A13FA91512, 0x53DB980E1579E0A5, 0x000058FEBFF3BE69, // XPB0
|
||||
0xA492034E7C075CC3, 0x677BAF00B04AA430, 0x3AAE0C9A755C94C8, 0x1DC4B064E9EBB08B, 0x3684EDD04E826C66, 0x9BAA6CB661F01B22,
|
||||
0x20285A00AD2EFE35, 0xDCE95ABD0497065F, 0x16C7FBB3778E3794, 0x26B3AC29CEF25AAF, 0xFB3C28A31A30AC1D, 0x000046ED190624EE, // XPB1
|
||||
0xF1A8C9ED7B96C4AB, 0x299429DA5178486E, 0xEF4926F20CD5C2F4, 0x683B2E2858B4716A, 0xDDA2FBCC3CAC3EEB, 0xEC055F9F3A600460,
|
||||
0xD5A5A17A58C3848B, 0x4652D836F42EAED5, 0x2F2E71ED78B3A3B3, 0xA771C057180ADD1D, 0xC780A5D2D835F512, 0x0000114EA3B55AC1, // XQB0
|
||||
0x1C0D6733769D0F31, 0xF084C3086E2659D1, 0xE23D5DA27BCBD133, 0xF38EC9A8D5864025, 0x6426DC781B3B645B, 0x4B24E8E3C9FB03EE,
|
||||
0x6432792F9D2CEA30, 0x7CC8E8B1AE76E857, 0x7F32BFB626BB8963, 0xB9F05995B48D7B74, 0x4D71200A7D67E042, 0x0000228457AF0637, // XRB0
|
||||
0x4AE37E7D8F72BD95, 0xDD2D504B3E993488, 0x5D14E7FA1ECB3C3E, 0x127610CEB75D6350, 0x255B4B4CAC446B11, 0x9EA12336C1F70CAF,
|
||||
0x79FA68A2147BC2F8, 0x11E895CFDADBBC49, 0xE4B9D3C4D6356C18, 0x44B25856A67F951C, 0x5851541F61308D0B, 0x00002FFD994F7E4C}; // 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 };
|
||||
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 };
|
||||
static const uint64_t Montgomery_one[NWORDS64_FIELD] = {0x00000000000249ad, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x8310000000000000,
|
||||
0x5527b1e4375c6c66, 0x697797bf3f4f24d0, 0xc89db7b2ac5c4e2e, 0x4ca4b439d2076956, 0x10f7926c7512c7e9, 0x00002d5b24bce5e2};
|
||||
// Value (2^384)^2 mod 3^239
|
||||
static const uint64_t Montgomery_Rprime[NWORDS64_ORDER] = { 0x1A55482318541298, 0x070A6370DFA12A03, 0xCB1658E0E3823A40, 0xB3B7384EB5DEF3F9, 0xCBCA952F7006EA33, 0x00569EF8EC94864C };
|
||||
static const uint64_t Montgomery_Rprime[NWORDS64_ORDER] = {0x1A55482318541298, 0x070A6370DFA12A03, 0xCB1658E0E3823A40, 0xB3B7384EB5DEF3F9, 0xCBCA952F7006EA33, 0x00569EF8EC94864C};
|
||||
// Value -(3^239)^-1 mod 2^384
|
||||
static const uint64_t Montgomery_rprime[NWORDS64_ORDER] = { 0x48062A91D3AB563D, 0x6CE572751303C2F5, 0x5D1319F3F160EC9D, 0xE35554E8C2D5623A, 0xCA29300232BC79A5, 0x8AAD843D646D78C5 };
|
||||
static const uint64_t Montgomery_rprime[NWORDS64_ORDER] = {0x48062A91D3AB563D, 0x6CE572751303C2F5, 0x5D1319F3F160EC9D, 0xE35554E8C2D5623A, 0xCA29300232BC79A5, 0x8AAD843D646D78C5};
|
||||
// Value order_Bob/3 mod p751
|
||||
static const uint64_t Border_div3[NWORDS_ORDER] = { 0xEDCD718A828384F9, 0x733B35BFD4427A14, 0xF88229CF94D7CF38, 0x63C56C990C7C2AD6, 0xB858A87E8F4222C7, 0x0254C9C6B525EAF5 };
|
||||
|
||||
static const uint64_t Border_div3[NWORDS_ORDER] = {0xEDCD718A828384F9, 0x733B35BFD4427A14, 0xF88229CF94D7CF38, 0x63C56C990C7C2AD6, 0xB858A87E8F4222C7, 0x0254C9C6B525EAF5};
|
||||
|
||||
// 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_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 };
|
||||
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 oqs_kex_sidh_msr_fpadd751
|
||||
#define fpsub oqs_kex_sidh_msr_fpsub751
|
||||
#define fpneg oqs_kex_sidh_msr_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 oqs_kex_sidh_msr_fp2add751
|
||||
#define fp2sub oqs_kex_sidh_msr_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 mp_add751_asm
|
||||
#define mp_addx2_asm mp_add751x2_asm
|
||||
#define mp_subx2_asm mp_sub751x2_asm
|
||||
#define crypto_kem_keypair crypto_kem_keypair_SIKEp751
|
||||
#define crypto_kem_enc crypto_kem_enc_SIKEp751
|
||||
#define crypto_kem_dec crypto_kem_dec_SIKEp751
|
||||
#define random_mod_order_A random_mod_order_A_SIDHp751
|
||||
#define random_mod_order_B random_mod_order_B_SIDHp751
|
||||
#define EphemeralKeyGeneration_A EphemeralKeyGeneration_A_SIDHp751
|
||||
#define EphemeralKeyGeneration_B EphemeralKeyGeneration_B_SIDHp751
|
||||
#define EphemeralSecretAgreement_A EphemeralSecretAgreement_A_SIDHp751
|
||||
#define EphemeralSecretAgreement_B EphemeralSecretAgreement_B_SIDHp751
|
||||
#define fpcopy fpcopy751
|
||||
#define fpzero fpzero751
|
||||
#define fpadd oqs_kex_sidh_msr_fpadd751
|
||||
#define fpsub oqs_kex_sidh_msr_fpsub751
|
||||
#define fpneg oqs_kex_sidh_msr_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 oqs_kex_sidh_msr_fp2add751
|
||||
#define fp2sub oqs_kex_sidh_msr_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 mp_add751_asm
|
||||
#define mp_addx2_asm mp_add751x2_asm
|
||||
#define mp_subx2_asm mp_sub751x2_asm
|
||||
#define crypto_kem_keypair crypto_kem_keypair_SIKEp751
|
||||
#define crypto_kem_enc crypto_kem_enc_SIKEp751
|
||||
#define crypto_kem_dec crypto_kem_dec_SIKEp751
|
||||
#define random_mod_order_A random_mod_order_A_SIDHp751
|
||||
#define random_mod_order_B random_mod_order_B_SIDHp751
|
||||
#define EphemeralKeyGeneration_A EphemeralKeyGeneration_A_SIDHp751
|
||||
#define EphemeralKeyGeneration_B EphemeralKeyGeneration_B_SIDHp751
|
||||
#define EphemeralSecretAgreement_A EphemeralSecretAgreement_A_SIDHp751
|
||||
#define EphemeralSecretAgreement_B EphemeralSecretAgreement_B_SIDHp751
|
||||
|
||||
#if defined(X86_64)
|
||||
#include "AMD64/fp_x64.c"
|
||||
|
||||
@ -9,13 +9,12 @@
|
||||
|
||||
#include <oqs/rand.h>
|
||||
|
||||
|
||||
/*********************** Key encapsulation mechanism API ***********************/
|
||||
|
||||
#define CRYPTO_SECRETKEYBYTES 644 // MSG_BYTES + SECRETKEY_B_BYTES + CRYPTO_PUBLICKEYBYTES bytes
|
||||
#define CRYPTO_PUBLICKEYBYTES 564
|
||||
#define CRYPTO_BYTES 24
|
||||
#define CRYPTO_CIPHERTEXTBYTES 596 // CRYPTO_PUBLICKEYBYTES + MSG_BYTES bytes
|
||||
#define CRYPTO_SECRETKEYBYTES 644 // MSG_BYTES + SECRETKEY_B_BYTES + CRYPTO_PUBLICKEYBYTES bytes
|
||||
#define CRYPTO_PUBLICKEYBYTES 564
|
||||
#define CRYPTO_BYTES 24
|
||||
#define CRYPTO_CIPHERTEXTBYTES 596 // CRYPTO_PUBLICKEYBYTES + MSG_BYTES bytes
|
||||
|
||||
// Algorithm name
|
||||
#define CRYPTO_ALGNAME "SIKEp751"
|
||||
@ -38,7 +37,6 @@ int crypto_kem_enc_SIKEp751(unsigned char *ct, unsigned char *ss, const unsigned
|
||||
// Outputs: shared secret ss (CRYPTO_BYTES = 24 bytes)
|
||||
int crypto_kem_dec_SIKEp751(unsigned char *ss, const unsigned char *ct, const unsigned char *sk, OQS_RAND *rand);
|
||||
|
||||
|
||||
// Encoding of keys for KEM-based isogeny system "SIKEp751" (wire format):
|
||||
// ----------------------------------------------------------------------
|
||||
// Elements over GF(p751) are encoded in 94 octets in little endian format (i.e., the least significant octet is located in the lowest memory address).
|
||||
@ -50,12 +48,11 @@ int crypto_kem_dec_SIKEp751(unsigned char *ss, const unsigned char *ct, const un
|
||||
// Ciphertexts ct consist of the concatenation of a public key value and a 32-byte value. In the SIKE API, ct is encoded in 564 + 32 = 596 octets.
|
||||
// Shared keys ss consist of a value of 24 octets.
|
||||
|
||||
|
||||
/*********************** Ephemeral key exchange API ***********************/
|
||||
|
||||
#define SIDH_SECRETKEYBYTES 48
|
||||
#define SIDH_PUBLICKEYBYTES 564
|
||||
#define SIDH_BYTES 188
|
||||
#define SIDH_SECRETKEYBYTES 48
|
||||
#define SIDH_PUBLICKEYBYTES 564
|
||||
#define SIDH_BYTES 188
|
||||
|
||||
// SECURITY NOTE: SIDH supports ephemeral Diffie-Hellman key exchange. It is NOT secure to use it with static keys.
|
||||
// See "On the Security of Supersingular Isogeny Cryptosystems", S.D. Galbraith, C. Petit, B. Shani and Y.B. Ti, in ASIACRYPT 2016, 2016.
|
||||
@ -63,37 +60,36 @@ int crypto_kem_dec_SIKEp751(unsigned char *ss, const unsigned char *ct, const un
|
||||
|
||||
// Generation of Alice's secret key
|
||||
// Outputs random value in [0, 2^372 - 1] to be used as Alice's private key
|
||||
void random_mod_order_A_SIDHp751(unsigned char* random_digits, OQS_RAND* rand);
|
||||
void random_mod_order_A_SIDHp751(unsigned char *random_digits, OQS_RAND *rand);
|
||||
|
||||
// Generation of Bob's secret key
|
||||
// Outputs random value in [0, 2^Floor(Log(2,3^239)) - 1] to be used as Bob's private key
|
||||
void random_mod_order_B_SIDHp751(unsigned char* random_digits, OQS_RAND* rand);
|
||||
void random_mod_order_B_SIDHp751(unsigned char *random_digits, OQS_RAND *rand);
|
||||
|
||||
// Alice's ephemeral public key generation
|
||||
// Input: a private key PrivateKeyA in the range [0, 2^372 - 1], stored in 47 bytes.
|
||||
// Output: the public key PublicKeyA consisting of 3 GF(p751^2) elements encoded in 564 bytes.
|
||||
int EphemeralKeyGeneration_A_SIDHp751(const unsigned char* PrivateKeyA, unsigned char* PublicKeyA, OQS_RAND* rand);
|
||||
int EphemeralKeyGeneration_A_SIDHp751(const unsigned char *PrivateKeyA, unsigned char *PublicKeyA, OQS_RAND *rand);
|
||||
|
||||
// Bob's ephemeral key-pair generation
|
||||
// It produces a private key PrivateKeyB and computes the public key PublicKeyB.
|
||||
// The private key is an integer in the range [0, 2^Floor(Log(2,3^239)) - 1], stored in 48 bytes.
|
||||
// The public key consists of 3 GF(p751^2) elements encoded in 564 bytes.
|
||||
int EphemeralKeyGeneration_B_SIDHp751(const unsigned char* PrivateKeyB, unsigned char* PublicKeyB, OQS_RAND* rand);
|
||||
int EphemeralKeyGeneration_B_SIDHp751(const unsigned char *PrivateKeyB, unsigned char *PublicKeyB, OQS_RAND *rand);
|
||||
|
||||
// Alice's ephemeral shared secret computation
|
||||
// It produces a shared secret key SharedSecretA using her secret key PrivateKeyA and Bob's public key PublicKeyB
|
||||
// Inputs: Alice's PrivateKeyA is an integer in the range [0, 2^372 - 1], stored in 47 bytes.
|
||||
// Bob's PublicKeyB consists of 3 GF(p751^2) elements encoded in 564 bytes.
|
||||
// Output: a shared secret SharedSecretA that consists of one element in GF(p751^2) encoded in 188 bytes.
|
||||
int EphemeralSecretAgreement_A_SIDHp751(const unsigned char* PrivateKeyA, const unsigned char* PublicKeyB, unsigned char* SharedSecretA);
|
||||
int EphemeralSecretAgreement_A_SIDHp751(const unsigned char *PrivateKeyA, const unsigned char *PublicKeyB, unsigned char *SharedSecretA);
|
||||
|
||||
// Bob's ephemeral shared secret computation
|
||||
// It produces a shared secret key SharedSecretB using his secret key PrivateKeyB and Alice's public key PublicKeyA
|
||||
// Inputs: Bob's PrivateKeyB is an integer in the range [0, 2^Floor(Log(2,3^239)) - 1], stored in 48 bytes.
|
||||
// Alice's PublicKeyA consists of 3 GF(p751^2) elements encoded in 564 bytes.
|
||||
// Output: a shared secret SharedSecretB that consists of one element in GF(p751^2) encoded in 188 bytes.
|
||||
int EphemeralSecretAgreement_B_SIDHp751(const unsigned char* PrivateKeyB, const unsigned char* PublicKeyA, unsigned char* SharedSecretB);
|
||||
|
||||
int EphemeralSecretAgreement_B_SIDHp751(const unsigned char *PrivateKeyB, const unsigned char *PublicKeyA, unsigned char *SharedSecretB);
|
||||
|
||||
// Encoding of keys for KEX-based isogeny system "SIDHp751" (wire format):
|
||||
// ----------------------------------------------------------------------
|
||||
@ -105,5 +101,4 @@ int EphemeralSecretAgreement_B_SIDHp751(const unsigned char* PrivateKeyB, const
|
||||
// Public keys PublicKeyA and PublicKeyB consist of 3 elements in GF(p751^2). In the SIDH API, they are encoded in 564 octets.
|
||||
// Shared keys SharedSecretA and SharedSecretB consist of one element in GF(p751^2). In the SIDH API, they are encoded in 188 octets.
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@ -6,219 +6,202 @@
|
||||
|
||||
#include "../P751_internal.h"
|
||||
|
||||
|
||||
// Global constants
|
||||
extern const uint64_t p751[NWORDS_FIELD];
|
||||
extern const uint64_t p751p1[NWORDS_FIELD];
|
||||
extern const uint64_t p751x2[NWORDS_FIELD];
|
||||
|
||||
__inline void oqs_kex_sidh_msr_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]
|
||||
unsigned int i, carry = 0;
|
||||
digit_t mask;
|
||||
|
||||
__inline void oqs_kex_sidh_msr_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]
|
||||
unsigned int i, carry = 0;
|
||||
digit_t mask;
|
||||
for (i = 0; i < NWORDS_FIELD; i++) {
|
||||
ADDC(carry, a[i], b[i], carry, c[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < NWORDS_FIELD; i++) {
|
||||
ADDC(carry, a[i], b[i], carry, c[i]);
|
||||
}
|
||||
carry = 0;
|
||||
for (i = 0; i < NWORDS_FIELD; i++) {
|
||||
SUBC(carry, c[i], ((digit_t *) p751x2)[i], carry, c[i]);
|
||||
}
|
||||
mask = 0 - (digit_t) carry;
|
||||
|
||||
carry = 0;
|
||||
for (i = 0; i < NWORDS_FIELD; i++) {
|
||||
SUBC(carry, c[i], ((digit_t*)p751x2)[i], carry, c[i]);
|
||||
}
|
||||
mask = 0 - (digit_t)carry;
|
||||
|
||||
carry = 0;
|
||||
for (i = 0; i < NWORDS_FIELD; i++) {
|
||||
ADDC(carry, c[i], ((digit_t*)p751x2)[i] & mask, carry, c[i]);
|
||||
}
|
||||
carry = 0;
|
||||
for (i = 0; i < NWORDS_FIELD; i++) {
|
||||
ADDC(carry, c[i], ((digit_t *) p751x2)[i] & mask, carry, c[i]);
|
||||
}
|
||||
}
|
||||
|
||||
__inline void oqs_kex_sidh_msr_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]
|
||||
unsigned int i, borrow = 0;
|
||||
digit_t mask;
|
||||
|
||||
__inline void oqs_kex_sidh_msr_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]
|
||||
unsigned int i, borrow = 0;
|
||||
digit_t mask;
|
||||
for (i = 0; i < NWORDS_FIELD; i++) {
|
||||
SUBC(borrow, a[i], b[i], borrow, c[i]);
|
||||
}
|
||||
mask = 0 - (digit_t) borrow;
|
||||
|
||||
for (i = 0; i < NWORDS_FIELD; i++) {
|
||||
SUBC(borrow, a[i], b[i], borrow, c[i]);
|
||||
}
|
||||
mask = 0 - (digit_t)borrow;
|
||||
|
||||
borrow = 0;
|
||||
for (i = 0; i < NWORDS_FIELD; i++) {
|
||||
ADDC(borrow, c[i], ((digit_t*)p751x2)[i] & mask, borrow, c[i]);
|
||||
}
|
||||
borrow = 0;
|
||||
for (i = 0; i < NWORDS_FIELD; i++) {
|
||||
ADDC(borrow, c[i], ((digit_t *) p751x2)[i] & mask, borrow, c[i]);
|
||||
}
|
||||
}
|
||||
|
||||
__inline void oqs_kex_sidh_msr_fpneg751(digit_t *a) { // Modular negation, a = -a mod p751.
|
||||
// Input/output: a in [0, 2*p751-1]
|
||||
unsigned int i, borrow = 0;
|
||||
|
||||
__inline void oqs_kex_sidh_msr_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]);
|
||||
}
|
||||
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;
|
||||
|
||||
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+p751
|
||||
for (i = 0; i < NWORDS_FIELD; i++) {
|
||||
ADDC(carry, a[i], ((digit_t *) p751)[i] & mask, carry, c[i]);
|
||||
}
|
||||
|
||||
mask = 0 - (digit_t)(a[0] & 1); // If a is odd compute a+p751
|
||||
for (i = 0; i < NWORDS_FIELD; i++) {
|
||||
ADDC(carry, a[i], ((digit_t*)p751)[i] & mask, carry, c[i]);
|
||||
}
|
||||
|
||||
mp_shiftr1(c, NWORDS_FIELD);
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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]);
|
||||
}
|
||||
borrow = 0;
|
||||
for (i = 0; i < NWORDS_FIELD; i++) {
|
||||
ADDC(borrow, a[i], ((digit_t *) p751)[i] & mask, borrow, a[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void digit_x_digit(const digit_t a, const digit_t b, digit_t *c) { // Digit multiplication, digit * digit -> 2-digit result
|
||||
register digit_t al, ah, bl, bh, temp;
|
||||
digit_t albl, albh, ahbl, ahbh, res1, res2, res3, carry;
|
||||
digit_t mask_low = (digit_t)(-1) >> (sizeof(digit_t) * 4), mask_high = (digit_t)(-1) << (sizeof(digit_t) * 4);
|
||||
|
||||
void digit_x_digit(const digit_t a, const digit_t b, digit_t* c)
|
||||
{ // Digit multiplication, digit * digit -> 2-digit result
|
||||
register digit_t al, ah, bl, bh, temp;
|
||||
digit_t albl, albh, ahbl, ahbh, res1, res2, res3, carry;
|
||||
digit_t mask_low = (digit_t)(-1) >> (sizeof(digit_t)*4), mask_high = (digit_t)(-1) << (sizeof(digit_t)*4);
|
||||
al = a & mask_low; // Low part
|
||||
ah = a >> (sizeof(digit_t) * 4); // High part
|
||||
bl = b & mask_low;
|
||||
bh = b >> (sizeof(digit_t) * 4);
|
||||
|
||||
al = a & mask_low; // Low part
|
||||
ah = a >> (sizeof(digit_t) * 4); // High part
|
||||
bl = b & mask_low;
|
||||
bh = b >> (sizeof(digit_t) * 4);
|
||||
albl = al * bl;
|
||||
albh = al * bh;
|
||||
ahbl = ah * bl;
|
||||
ahbh = ah * bh;
|
||||
c[0] = albl & mask_low; // C00
|
||||
|
||||
albl = al*bl;
|
||||
albh = al*bh;
|
||||
ahbl = ah*bl;
|
||||
ahbh = ah*bh;
|
||||
c[0] = albl & mask_low; // C00
|
||||
res1 = albl >> (sizeof(digit_t) * 4);
|
||||
res2 = ahbl & mask_low;
|
||||
res3 = albh & mask_low;
|
||||
temp = res1 + res2 + res3;
|
||||
carry = temp >> (sizeof(digit_t) * 4);
|
||||
c[0] ^= temp << (sizeof(digit_t) * 4); // C01
|
||||
|
||||
res1 = albl >> (sizeof(digit_t) * 4);
|
||||
res2 = ahbl & mask_low;
|
||||
res3 = albh & mask_low;
|
||||
temp = res1 + res2 + res3;
|
||||
carry = temp >> (sizeof(digit_t) * 4);
|
||||
c[0] ^= temp << (sizeof(digit_t) * 4); // C01
|
||||
|
||||
res1 = ahbl >> (sizeof(digit_t) * 4);
|
||||
res2 = albh >> (sizeof(digit_t) * 4);
|
||||
res3 = ahbh & mask_low;
|
||||
temp = res1 + res2 + res3 + carry;
|
||||
c[1] = temp & mask_low; // C10
|
||||
carry = temp & mask_high;
|
||||
c[1] ^= (ahbh & mask_high) + carry; // C11
|
||||
res1 = ahbl >> (sizeof(digit_t) * 4);
|
||||
res2 = albh >> (sizeof(digit_t) * 4);
|
||||
res3 = ahbh & mask_low;
|
||||
temp = res1 + res2 + res3 + carry;
|
||||
c[1] = temp & mask_low; // C10
|
||||
carry = temp & mask_high;
|
||||
c[1] ^= (ahbh & mask_high) + carry; // C11
|
||||
}
|
||||
|
||||
void mp_mul(const digit_t *a, const digit_t *b, digit_t *c, const unsigned int nwords) { // Multiprecision comba multiply, c = a*b, where lng(a) = lng(b) = nwords.
|
||||
unsigned int i, j;
|
||||
digit_t t = 0, u = 0, v = 0, UV[2];
|
||||
unsigned int carry = 0;
|
||||
|
||||
void mp_mul(const digit_t* a, const digit_t* b, digit_t* c, const unsigned int nwords)
|
||||
{ // Multiprecision comba multiply, c = a*b, where lng(a) = lng(b) = nwords.
|
||||
unsigned int i, j;
|
||||
digit_t t = 0, u = 0, v = 0, UV[2];
|
||||
unsigned int carry = 0;
|
||||
for (i = 0; i < nwords; i++) {
|
||||
for (j = 0; j <= i; j++) {
|
||||
MUL(a[j], b[i - j], UV + 1, UV[0]);
|
||||
ADDC(0, UV[0], v, carry, v);
|
||||
ADDC(carry, UV[1], u, carry, u);
|
||||
t += carry;
|
||||
}
|
||||
c[i] = v;
|
||||
v = u;
|
||||
u = t;
|
||||
t = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < nwords; i++) {
|
||||
for (j = 0; j <= i; j++) {
|
||||
MUL(a[j], b[i-j], UV+1, UV[0]);
|
||||
ADDC(0, UV[0], v, carry, v);
|
||||
ADDC(carry, UV[1], u, carry, u);
|
||||
t += carry;
|
||||
}
|
||||
c[i] = v;
|
||||
v = u;
|
||||
u = t;
|
||||
t = 0;
|
||||
}
|
||||
|
||||
for (i = nwords; i < 2*nwords-1; i++) {
|
||||
for (j = i-nwords+1; j < nwords; j++) {
|
||||
MUL(a[j], b[i-j], UV+1, UV[0]);
|
||||
ADDC(0, UV[0], v, carry, v);
|
||||
ADDC(carry, UV[1], u, carry, u);
|
||||
t += carry;
|
||||
}
|
||||
c[i] = v;
|
||||
v = u;
|
||||
u = t;
|
||||
t = 0;
|
||||
}
|
||||
c[2*nwords-1] = v;
|
||||
for (i = nwords; i < 2 * nwords - 1; i++) {
|
||||
for (j = i - nwords + 1; j < nwords; j++) {
|
||||
MUL(a[j], b[i - j], UV + 1, UV[0]);
|
||||
ADDC(0, UV[0], v, carry, v);
|
||||
ADDC(carry, UV[1], u, carry, u);
|
||||
t += carry;
|
||||
}
|
||||
c[i] = v;
|
||||
v = u;
|
||||
u = t;
|
||||
t = 0;
|
||||
}
|
||||
c[2 * nwords - 1] = v;
|
||||
}
|
||||
|
||||
void rdc_mont(const digit_t *ma, digit_t *mc) { // Efficient Montgomery reduction using comba and exploiting the special form of the prime p751.
|
||||
// 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.
|
||||
unsigned int i, j, carry, count = p751_ZERO_WORDS;
|
||||
digit_t UV[2], t = 0, u = 0, v = 0;
|
||||
|
||||
void rdc_mont(const digit_t* ma, digit_t* mc)
|
||||
{ // Efficient Montgomery reduction using comba and exploiting the special form of the prime p751.
|
||||
// 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.
|
||||
unsigned int i, j, carry, count = p751_ZERO_WORDS;
|
||||
digit_t UV[2], t = 0, u = 0, v = 0;
|
||||
for (i = 0; i < NWORDS_FIELD; i++) {
|
||||
mc[i] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < NWORDS_FIELD; i++) {
|
||||
mc[i] = 0;
|
||||
}
|
||||
for (i = 0; i < NWORDS_FIELD; i++) {
|
||||
for (j = 0; j < i; j++) {
|
||||
if (j < (i - p751_ZERO_WORDS + 1)) {
|
||||
MUL(mc[j], ((digit_t *) p751p1)[i - j], UV + 1, UV[0]);
|
||||
ADDC(0, UV[0], v, carry, v);
|
||||
ADDC(carry, UV[1], u, carry, u);
|
||||
t += carry;
|
||||
}
|
||||
}
|
||||
ADDC(0, v, ma[i], carry, v);
|
||||
ADDC(carry, u, 0, carry, u);
|
||||
t += carry;
|
||||
mc[i] = v;
|
||||
v = u;
|
||||
u = t;
|
||||
t = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < NWORDS_FIELD; i++) {
|
||||
for (j = 0; j < i; j++) {
|
||||
if (j < (i-p751_ZERO_WORDS+1)) {
|
||||
MUL(mc[j], ((digit_t*)p751p1)[i-j], UV+1, UV[0]);
|
||||
ADDC(0, UV[0], v, carry, v);
|
||||
ADDC(carry, UV[1], u, carry, u);
|
||||
t += carry;
|
||||
}
|
||||
}
|
||||
ADDC(0, v, ma[i], carry, v);
|
||||
ADDC(carry, u, 0, carry, u);
|
||||
t += carry;
|
||||
mc[i] = v;
|
||||
v = u;
|
||||
u = t;
|
||||
t = 0;
|
||||
}
|
||||
|
||||
for (i = NWORDS_FIELD; i < 2*NWORDS_FIELD-1; i++) {
|
||||
if (count > 0) {
|
||||
count -= 1;
|
||||
}
|
||||
for (j = i-NWORDS_FIELD+1; j < NWORDS_FIELD; j++) {
|
||||
if (j < (NWORDS_FIELD-count)) {
|
||||
MUL(mc[j], ((digit_t*)p751p1)[i-j], UV+1, UV[0]);
|
||||
ADDC(0, UV[0], v, carry, v);
|
||||
ADDC(carry, UV[1], u, carry, u);
|
||||
t += carry;
|
||||
}
|
||||
}
|
||||
ADDC(0, v, ma[i], carry, v);
|
||||
ADDC(carry, u, 0, carry, u);
|
||||
t += carry;
|
||||
mc[i-NWORDS_FIELD] = v;
|
||||
v = u;
|
||||
u = t;
|
||||
t = 0;
|
||||
}
|
||||
ADDC(0, v, ma[2*NWORDS_FIELD-1], carry, v);
|
||||
mc[NWORDS_FIELD-1] = v;
|
||||
for (i = NWORDS_FIELD; i < 2 * NWORDS_FIELD - 1; i++) {
|
||||
if (count > 0) {
|
||||
count -= 1;
|
||||
}
|
||||
for (j = i - NWORDS_FIELD + 1; j < NWORDS_FIELD; j++) {
|
||||
if (j < (NWORDS_FIELD - count)) {
|
||||
MUL(mc[j], ((digit_t *) p751p1)[i - j], UV + 1, UV[0]);
|
||||
ADDC(0, UV[0], v, carry, v);
|
||||
ADDC(carry, UV[1], u, carry, u);
|
||||
t += carry;
|
||||
}
|
||||
}
|
||||
ADDC(0, v, ma[i], carry, v);
|
||||
ADDC(carry, u, 0, carry, u);
|
||||
t += carry;
|
||||
mc[i - NWORDS_FIELD] = v;
|
||||
v = u;
|
||||
u = t;
|
||||
t = 0;
|
||||
}
|
||||
ADDC(0, v, ma[2 * NWORDS_FIELD - 1], carry, v);
|
||||
mc[NWORDS_FIELD - 1] = v;
|
||||
}
|
||||
|
||||
@ -63,7 +63,7 @@ OQS_KEX *OQS_KEX_sidh_msr_new(OQS_RAND *rand, const char *named_parameters) {
|
||||
if (strcmp(named_parameters, OQS_KEX_SIDH_503_params) == 0) {
|
||||
k->method_name = strdup("SIDH MSR p503");
|
||||
k->estimated_classical_security = 126; // same as AES128
|
||||
k->estimated_quantum_security = 84; // same as AES128
|
||||
k->estimated_quantum_security = 84; // same as AES128
|
||||
k->named_parameters = OQS_KEX_SIDH_503_params;
|
||||
sidh_ctx->is_sidh = 1;
|
||||
// from P503_api.h
|
||||
@ -77,7 +77,7 @@ OQS_KEX *OQS_KEX_sidh_msr_new(OQS_RAND *rand, const char *named_parameters) {
|
||||
} else if (strcmp(named_parameters, OQS_KEX_SIDH_751_params) == 0) {
|
||||
k->method_name = strdup("SIDH MSR p751");
|
||||
k->estimated_classical_security = 188; // same as AES192
|
||||
k->estimated_quantum_security = 125; // same as AES192
|
||||
k->estimated_quantum_security = 125; // same as AES192
|
||||
k->named_parameters = OQS_KEX_SIDH_751_params;
|
||||
sidh_ctx->is_sidh = 1;
|
||||
// from P751_api.h
|
||||
@ -90,8 +90,8 @@ OQS_KEX *OQS_KEX_sidh_msr_new(OQS_RAND *rand, const char *named_parameters) {
|
||||
sidh_ctx->EphemeralSecretAgreement_B = &EphemeralSecretAgreement_B_SIDHp751;
|
||||
} else if (strcmp(named_parameters, OQS_KEX_SIKE_503_params) == 0) {
|
||||
k->method_name = strdup("SIKE MSR p503");
|
||||
k->estimated_classical_security = 126; // same as AES128
|
||||
k->estimated_quantum_security = 84; // same as AES128
|
||||
k->estimated_classical_security = 126; // same as AES128
|
||||
k->estimated_quantum_security = 84; // same as AES128
|
||||
k->named_parameters = OQS_KEX_SIKE_503_params;
|
||||
sidh_ctx->is_sidh = 0;
|
||||
// from P503_api.h
|
||||
@ -105,7 +105,7 @@ OQS_KEX *OQS_KEX_sidh_msr_new(OQS_RAND *rand, const char *named_parameters) {
|
||||
} else if (strcmp(named_parameters, OQS_KEX_SIKE_751_params) == 0) {
|
||||
k->method_name = strdup("SIKE MSR p751");
|
||||
k->estimated_classical_security = 188; // same as AES192
|
||||
k->estimated_quantum_security = 125; // same as AES192
|
||||
k->estimated_quantum_security = 125; // same as AES192
|
||||
k->named_parameters = OQS_KEX_SIKE_751_params;
|
||||
sidh_ctx->is_sidh = 0;
|
||||
// from P751_api.h
|
||||
|
||||
@ -16,558 +16,514 @@
|
||||
#include "fips202.h"
|
||||
|
||||
#define NROUNDS 24
|
||||
#define ROL(a, offset) ((a << offset) ^ (a >> (64-offset)))
|
||||
#define ROL(a, offset) ((a << offset) ^ (a >> (64 - offset)))
|
||||
|
||||
static uint64_t load64(const unsigned char *x) {
|
||||
unsigned long long r = 0, i;
|
||||
|
||||
static uint64_t load64(const unsigned char *x)
|
||||
{
|
||||
unsigned long long r = 0, i;
|
||||
|
||||
for (i = 0; i < 8; ++i) {
|
||||
r |= (unsigned long long)x[i] << 8 * i;
|
||||
}
|
||||
return r;
|
||||
for (i = 0; i < 8; ++i) {
|
||||
r |= (unsigned long long) x[i] << 8 * i;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
static void store64(uint8_t *x, uint64_t u) {
|
||||
unsigned int i;
|
||||
|
||||
static void store64(uint8_t *x, uint64_t u)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < 8; ++i) {
|
||||
x[i] = (uint8_t)u;
|
||||
u >>= 8;
|
||||
}
|
||||
for (i = 0; i < 8; ++i) {
|
||||
x[i] = (uint8_t) u;
|
||||
u >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const uint64_t KeccakF_RoundConstants[NROUNDS] =
|
||||
{
|
||||
(uint64_t)0x0000000000000001ULL,
|
||||
(uint64_t)0x0000000000008082ULL,
|
||||
(uint64_t)0x800000000000808aULL,
|
||||
(uint64_t)0x8000000080008000ULL,
|
||||
(uint64_t)0x000000000000808bULL,
|
||||
(uint64_t)0x0000000080000001ULL,
|
||||
(uint64_t)0x8000000080008081ULL,
|
||||
(uint64_t)0x8000000000008009ULL,
|
||||
(uint64_t)0x000000000000008aULL,
|
||||
(uint64_t)0x0000000000000088ULL,
|
||||
(uint64_t)0x0000000080008009ULL,
|
||||
(uint64_t)0x000000008000000aULL,
|
||||
(uint64_t)0x000000008000808bULL,
|
||||
(uint64_t)0x800000000000008bULL,
|
||||
(uint64_t)0x8000000000008089ULL,
|
||||
(uint64_t)0x8000000000008003ULL,
|
||||
(uint64_t)0x8000000000008002ULL,
|
||||
(uint64_t)0x8000000000000080ULL,
|
||||
(uint64_t)0x000000000000800aULL,
|
||||
(uint64_t)0x800000008000000aULL,
|
||||
(uint64_t)0x8000000080008081ULL,
|
||||
(uint64_t)0x8000000000008080ULL,
|
||||
(uint64_t)0x0000000080000001ULL,
|
||||
(uint64_t)0x8000000080008008ULL
|
||||
};
|
||||
{
|
||||
(uint64_t) 0x0000000000000001ULL,
|
||||
(uint64_t) 0x0000000000008082ULL,
|
||||
(uint64_t) 0x800000000000808aULL,
|
||||
(uint64_t) 0x8000000080008000ULL,
|
||||
(uint64_t) 0x000000000000808bULL,
|
||||
(uint64_t) 0x0000000080000001ULL,
|
||||
(uint64_t) 0x8000000080008081ULL,
|
||||
(uint64_t) 0x8000000000008009ULL,
|
||||
(uint64_t) 0x000000000000008aULL,
|
||||
(uint64_t) 0x0000000000000088ULL,
|
||||
(uint64_t) 0x0000000080008009ULL,
|
||||
(uint64_t) 0x000000008000000aULL,
|
||||
(uint64_t) 0x000000008000808bULL,
|
||||
(uint64_t) 0x800000000000008bULL,
|
||||
(uint64_t) 0x8000000000008089ULL,
|
||||
(uint64_t) 0x8000000000008003ULL,
|
||||
(uint64_t) 0x8000000000008002ULL,
|
||||
(uint64_t) 0x8000000000000080ULL,
|
||||
(uint64_t) 0x000000000000800aULL,
|
||||
(uint64_t) 0x800000008000000aULL,
|
||||
(uint64_t) 0x8000000080008081ULL,
|
||||
(uint64_t) 0x8000000000008080ULL,
|
||||
(uint64_t) 0x0000000080000001ULL,
|
||||
(uint64_t) 0x8000000080008008ULL};
|
||||
|
||||
void KeccakF1600_StatePermute(uint64_t *state) {
|
||||
int round;
|
||||
|
||||
void KeccakF1600_StatePermute(uint64_t * state)
|
||||
{
|
||||
int round;
|
||||
uint64_t Aba, Abe, Abi, Abo, Abu;
|
||||
uint64_t Aga, Age, Agi, Ago, Agu;
|
||||
uint64_t Aka, Ake, Aki, Ako, Aku;
|
||||
uint64_t Ama, Ame, Ami, Amo, Amu;
|
||||
uint64_t Asa, Ase, Asi, Aso, Asu;
|
||||
uint64_t BCa, BCe, BCi, BCo, BCu;
|
||||
uint64_t Da, De, Di, Do, Du;
|
||||
uint64_t Eba, Ebe, Ebi, Ebo, Ebu;
|
||||
uint64_t Ega, Ege, Egi, Ego, Egu;
|
||||
uint64_t Eka, Eke, Eki, Eko, Eku;
|
||||
uint64_t Ema, Eme, Emi, Emo, Emu;
|
||||
uint64_t Esa, Ese, Esi, Eso, Esu;
|
||||
|
||||
uint64_t Aba, Abe, Abi, Abo, Abu;
|
||||
uint64_t Aga, Age, Agi, Ago, Agu;
|
||||
uint64_t Aka, Ake, Aki, Ako, Aku;
|
||||
uint64_t Ama, Ame, Ami, Amo, Amu;
|
||||
uint64_t Asa, Ase, Asi, Aso, Asu;
|
||||
uint64_t BCa, BCe, BCi, BCo, BCu;
|
||||
uint64_t Da, De, Di, Do, Du;
|
||||
uint64_t Eba, Ebe, Ebi, Ebo, Ebu;
|
||||
uint64_t Ega, Ege, Egi, Ego, Egu;
|
||||
uint64_t Eka, Eke, Eki, Eko, Eku;
|
||||
uint64_t Ema, Eme, Emi, Emo, Emu;
|
||||
uint64_t Esa, Ese, Esi, Eso, Esu;
|
||||
//copyFromState(A, state)
|
||||
Aba = state[0];
|
||||
Abe = state[1];
|
||||
Abi = state[2];
|
||||
Abo = state[3];
|
||||
Abu = state[4];
|
||||
Aga = state[5];
|
||||
Age = state[6];
|
||||
Agi = state[7];
|
||||
Ago = state[8];
|
||||
Agu = state[9];
|
||||
Aka = state[10];
|
||||
Ake = state[11];
|
||||
Aki = state[12];
|
||||
Ako = state[13];
|
||||
Aku = state[14];
|
||||
Ama = state[15];
|
||||
Ame = state[16];
|
||||
Ami = state[17];
|
||||
Amo = state[18];
|
||||
Amu = state[19];
|
||||
Asa = state[20];
|
||||
Ase = state[21];
|
||||
Asi = state[22];
|
||||
Aso = state[23];
|
||||
Asu = state[24];
|
||||
|
||||
//copyFromState(A, state)
|
||||
Aba = state[ 0];
|
||||
Abe = state[ 1];
|
||||
Abi = state[ 2];
|
||||
Abo = state[ 3];
|
||||
Abu = state[ 4];
|
||||
Aga = state[ 5];
|
||||
Age = state[ 6];
|
||||
Agi = state[ 7];
|
||||
Ago = state[ 8];
|
||||
Agu = state[ 9];
|
||||
Aka = state[10];
|
||||
Ake = state[11];
|
||||
Aki = state[12];
|
||||
Ako = state[13];
|
||||
Aku = state[14];
|
||||
Ama = state[15];
|
||||
Ame = state[16];
|
||||
Ami = state[17];
|
||||
Amo = state[18];
|
||||
Amu = state[19];
|
||||
Asa = state[20];
|
||||
Ase = state[21];
|
||||
Asi = state[22];
|
||||
Aso = state[23];
|
||||
Asu = state[24];
|
||||
for (round = 0; round < NROUNDS; round += 2) {
|
||||
// prepareTheta
|
||||
BCa = Aba ^ Aga ^ Aka ^ Ama ^ Asa;
|
||||
BCe = Abe ^ Age ^ Ake ^ Ame ^ Ase;
|
||||
BCi = Abi ^ Agi ^ Aki ^ Ami ^ Asi;
|
||||
BCo = Abo ^ Ago ^ Ako ^ Amo ^ Aso;
|
||||
BCu = Abu ^ Agu ^ Aku ^ Amu ^ Asu;
|
||||
|
||||
for( round = 0; round < NROUNDS; round += 2 )
|
||||
{
|
||||
// prepareTheta
|
||||
BCa = Aba^Aga^Aka^Ama^Asa;
|
||||
BCe = Abe^Age^Ake^Ame^Ase;
|
||||
BCi = Abi^Agi^Aki^Ami^Asi;
|
||||
BCo = Abo^Ago^Ako^Amo^Aso;
|
||||
BCu = Abu^Agu^Aku^Amu^Asu;
|
||||
//thetaRhoPiChiIotaPrepareTheta(round , A, E)
|
||||
Da = BCu ^ ROL(BCe, 1);
|
||||
De = BCa ^ ROL(BCi, 1);
|
||||
Di = BCe ^ ROL(BCo, 1);
|
||||
Do = BCi ^ ROL(BCu, 1);
|
||||
Du = BCo ^ ROL(BCa, 1);
|
||||
|
||||
//thetaRhoPiChiIotaPrepareTheta(round , A, E)
|
||||
Da = BCu^ROL(BCe, 1);
|
||||
De = BCa^ROL(BCi, 1);
|
||||
Di = BCe^ROL(BCo, 1);
|
||||
Do = BCi^ROL(BCu, 1);
|
||||
Du = BCo^ROL(BCa, 1);
|
||||
Aba ^= Da;
|
||||
BCa = Aba;
|
||||
Age ^= De;
|
||||
BCe = ROL(Age, 44);
|
||||
Aki ^= Di;
|
||||
BCi = ROL(Aki, 43);
|
||||
Amo ^= Do;
|
||||
BCo = ROL(Amo, 21);
|
||||
Asu ^= Du;
|
||||
BCu = ROL(Asu, 14);
|
||||
Eba = BCa ^ ((~BCe) & BCi);
|
||||
Eba ^= (uint64_t) KeccakF_RoundConstants[round];
|
||||
Ebe = BCe ^ ((~BCi) & BCo);
|
||||
Ebi = BCi ^ ((~BCo) & BCu);
|
||||
Ebo = BCo ^ ((~BCu) & BCa);
|
||||
Ebu = BCu ^ ((~BCa) & BCe);
|
||||
|
||||
Aba ^= Da;
|
||||
BCa = Aba;
|
||||
Age ^= De;
|
||||
BCe = ROL(Age, 44);
|
||||
Aki ^= Di;
|
||||
BCi = ROL(Aki, 43);
|
||||
Amo ^= Do;
|
||||
BCo = ROL(Amo, 21);
|
||||
Asu ^= Du;
|
||||
BCu = ROL(Asu, 14);
|
||||
Eba = BCa ^((~BCe)& BCi );
|
||||
Eba ^= (uint64_t)KeccakF_RoundConstants[round];
|
||||
Ebe = BCe ^((~BCi)& BCo );
|
||||
Ebi = BCi ^((~BCo)& BCu );
|
||||
Ebo = BCo ^((~BCu)& BCa );
|
||||
Ebu = BCu ^((~BCa)& BCe );
|
||||
Abo ^= Do;
|
||||
BCa = ROL(Abo, 28);
|
||||
Agu ^= Du;
|
||||
BCe = ROL(Agu, 20);
|
||||
Aka ^= Da;
|
||||
BCi = ROL(Aka, 3);
|
||||
Ame ^= De;
|
||||
BCo = ROL(Ame, 45);
|
||||
Asi ^= Di;
|
||||
BCu = ROL(Asi, 61);
|
||||
Ega = BCa ^ ((~BCe) & BCi);
|
||||
Ege = BCe ^ ((~BCi) & BCo);
|
||||
Egi = BCi ^ ((~BCo) & BCu);
|
||||
Ego = BCo ^ ((~BCu) & BCa);
|
||||
Egu = BCu ^ ((~BCa) & BCe);
|
||||
|
||||
Abo ^= Do;
|
||||
BCa = ROL(Abo, 28);
|
||||
Agu ^= Du;
|
||||
BCe = ROL(Agu, 20);
|
||||
Aka ^= Da;
|
||||
BCi = ROL(Aka, 3);
|
||||
Ame ^= De;
|
||||
BCo = ROL(Ame, 45);
|
||||
Asi ^= Di;
|
||||
BCu = ROL(Asi, 61);
|
||||
Ega = BCa ^((~BCe)& BCi );
|
||||
Ege = BCe ^((~BCi)& BCo );
|
||||
Egi = BCi ^((~BCo)& BCu );
|
||||
Ego = BCo ^((~BCu)& BCa );
|
||||
Egu = BCu ^((~BCa)& BCe );
|
||||
Abe ^= De;
|
||||
BCa = ROL(Abe, 1);
|
||||
Agi ^= Di;
|
||||
BCe = ROL(Agi, 6);
|
||||
Ako ^= Do;
|
||||
BCi = ROL(Ako, 25);
|
||||
Amu ^= Du;
|
||||
BCo = ROL(Amu, 8);
|
||||
Asa ^= Da;
|
||||
BCu = ROL(Asa, 18);
|
||||
Eka = BCa ^ ((~BCe) & BCi);
|
||||
Eke = BCe ^ ((~BCi) & BCo);
|
||||
Eki = BCi ^ ((~BCo) & BCu);
|
||||
Eko = BCo ^ ((~BCu) & BCa);
|
||||
Eku = BCu ^ ((~BCa) & BCe);
|
||||
|
||||
Abe ^= De;
|
||||
BCa = ROL(Abe, 1);
|
||||
Agi ^= Di;
|
||||
BCe = ROL(Agi, 6);
|
||||
Ako ^= Do;
|
||||
BCi = ROL(Ako, 25);
|
||||
Amu ^= Du;
|
||||
BCo = ROL(Amu, 8);
|
||||
Asa ^= Da;
|
||||
BCu = ROL(Asa, 18);
|
||||
Eka = BCa ^((~BCe)& BCi );
|
||||
Eke = BCe ^((~BCi)& BCo );
|
||||
Eki = BCi ^((~BCo)& BCu );
|
||||
Eko = BCo ^((~BCu)& BCa );
|
||||
Eku = BCu ^((~BCa)& BCe );
|
||||
Abu ^= Du;
|
||||
BCa = ROL(Abu, 27);
|
||||
Aga ^= Da;
|
||||
BCe = ROL(Aga, 36);
|
||||
Ake ^= De;
|
||||
BCi = ROL(Ake, 10);
|
||||
Ami ^= Di;
|
||||
BCo = ROL(Ami, 15);
|
||||
Aso ^= Do;
|
||||
BCu = ROL(Aso, 56);
|
||||
Ema = BCa ^ ((~BCe) & BCi);
|
||||
Eme = BCe ^ ((~BCi) & BCo);
|
||||
Emi = BCi ^ ((~BCo) & BCu);
|
||||
Emo = BCo ^ ((~BCu) & BCa);
|
||||
Emu = BCu ^ ((~BCa) & BCe);
|
||||
|
||||
Abu ^= Du;
|
||||
BCa = ROL(Abu, 27);
|
||||
Aga ^= Da;
|
||||
BCe = ROL(Aga, 36);
|
||||
Ake ^= De;
|
||||
BCi = ROL(Ake, 10);
|
||||
Ami ^= Di;
|
||||
BCo = ROL(Ami, 15);
|
||||
Aso ^= Do;
|
||||
BCu = ROL(Aso, 56);
|
||||
Ema = BCa ^((~BCe)& BCi );
|
||||
Eme = BCe ^((~BCi)& BCo );
|
||||
Emi = BCi ^((~BCo)& BCu );
|
||||
Emo = BCo ^((~BCu)& BCa );
|
||||
Emu = BCu ^((~BCa)& BCe );
|
||||
Abi ^= Di;
|
||||
BCa = ROL(Abi, 62);
|
||||
Ago ^= Do;
|
||||
BCe = ROL(Ago, 55);
|
||||
Aku ^= Du;
|
||||
BCi = ROL(Aku, 39);
|
||||
Ama ^= Da;
|
||||
BCo = ROL(Ama, 41);
|
||||
Ase ^= De;
|
||||
BCu = ROL(Ase, 2);
|
||||
Esa = BCa ^ ((~BCe) & BCi);
|
||||
Ese = BCe ^ ((~BCi) & BCo);
|
||||
Esi = BCi ^ ((~BCo) & BCu);
|
||||
Eso = BCo ^ ((~BCu) & BCa);
|
||||
Esu = BCu ^ ((~BCa) & BCe);
|
||||
|
||||
Abi ^= Di;
|
||||
BCa = ROL(Abi, 62);
|
||||
Ago ^= Do;
|
||||
BCe = ROL(Ago, 55);
|
||||
Aku ^= Du;
|
||||
BCi = ROL(Aku, 39);
|
||||
Ama ^= Da;
|
||||
BCo = ROL(Ama, 41);
|
||||
Ase ^= De;
|
||||
BCu = ROL(Ase, 2);
|
||||
Esa = BCa ^((~BCe)& BCi );
|
||||
Ese = BCe ^((~BCi)& BCo );
|
||||
Esi = BCi ^((~BCo)& BCu );
|
||||
Eso = BCo ^((~BCu)& BCa );
|
||||
Esu = BCu ^((~BCa)& BCe );
|
||||
// prepareTheta
|
||||
BCa = Eba ^ Ega ^ Eka ^ Ema ^ Esa;
|
||||
BCe = Ebe ^ Ege ^ Eke ^ Eme ^ Ese;
|
||||
BCi = Ebi ^ Egi ^ Eki ^ Emi ^ Esi;
|
||||
BCo = Ebo ^ Ego ^ Eko ^ Emo ^ Eso;
|
||||
BCu = Ebu ^ Egu ^ Eku ^ Emu ^ Esu;
|
||||
|
||||
// prepareTheta
|
||||
BCa = Eba^Ega^Eka^Ema^Esa;
|
||||
BCe = Ebe^Ege^Eke^Eme^Ese;
|
||||
BCi = Ebi^Egi^Eki^Emi^Esi;
|
||||
BCo = Ebo^Ego^Eko^Emo^Eso;
|
||||
BCu = Ebu^Egu^Eku^Emu^Esu;
|
||||
//thetaRhoPiChiIotaPrepareTheta(round+1, E, A)
|
||||
Da = BCu ^ ROL(BCe, 1);
|
||||
De = BCa ^ ROL(BCi, 1);
|
||||
Di = BCe ^ ROL(BCo, 1);
|
||||
Do = BCi ^ ROL(BCu, 1);
|
||||
Du = BCo ^ ROL(BCa, 1);
|
||||
|
||||
//thetaRhoPiChiIotaPrepareTheta(round+1, E, A)
|
||||
Da = BCu^ROL(BCe, 1);
|
||||
De = BCa^ROL(BCi, 1);
|
||||
Di = BCe^ROL(BCo, 1);
|
||||
Do = BCi^ROL(BCu, 1);
|
||||
Du = BCo^ROL(BCa, 1);
|
||||
Eba ^= Da;
|
||||
BCa = Eba;
|
||||
Ege ^= De;
|
||||
BCe = ROL(Ege, 44);
|
||||
Eki ^= Di;
|
||||
BCi = ROL(Eki, 43);
|
||||
Emo ^= Do;
|
||||
BCo = ROL(Emo, 21);
|
||||
Esu ^= Du;
|
||||
BCu = ROL(Esu, 14);
|
||||
Aba = BCa ^ ((~BCe) & BCi);
|
||||
Aba ^= (uint64_t) KeccakF_RoundConstants[round + 1];
|
||||
Abe = BCe ^ ((~BCi) & BCo);
|
||||
Abi = BCi ^ ((~BCo) & BCu);
|
||||
Abo = BCo ^ ((~BCu) & BCa);
|
||||
Abu = BCu ^ ((~BCa) & BCe);
|
||||
|
||||
Eba ^= Da;
|
||||
BCa = Eba;
|
||||
Ege ^= De;
|
||||
BCe = ROL(Ege, 44);
|
||||
Eki ^= Di;
|
||||
BCi = ROL(Eki, 43);
|
||||
Emo ^= Do;
|
||||
BCo = ROL(Emo, 21);
|
||||
Esu ^= Du;
|
||||
BCu = ROL(Esu, 14);
|
||||
Aba = BCa ^((~BCe)& BCi );
|
||||
Aba ^= (uint64_t)KeccakF_RoundConstants[round+1];
|
||||
Abe = BCe ^((~BCi)& BCo );
|
||||
Abi = BCi ^((~BCo)& BCu );
|
||||
Abo = BCo ^((~BCu)& BCa );
|
||||
Abu = BCu ^((~BCa)& BCe );
|
||||
Ebo ^= Do;
|
||||
BCa = ROL(Ebo, 28);
|
||||
Egu ^= Du;
|
||||
BCe = ROL(Egu, 20);
|
||||
Eka ^= Da;
|
||||
BCi = ROL(Eka, 3);
|
||||
Eme ^= De;
|
||||
BCo = ROL(Eme, 45);
|
||||
Esi ^= Di;
|
||||
BCu = ROL(Esi, 61);
|
||||
Aga = BCa ^ ((~BCe) & BCi);
|
||||
Age = BCe ^ ((~BCi) & BCo);
|
||||
Agi = BCi ^ ((~BCo) & BCu);
|
||||
Ago = BCo ^ ((~BCu) & BCa);
|
||||
Agu = BCu ^ ((~BCa) & BCe);
|
||||
|
||||
Ebo ^= Do;
|
||||
BCa = ROL(Ebo, 28);
|
||||
Egu ^= Du;
|
||||
BCe = ROL(Egu, 20);
|
||||
Eka ^= Da;
|
||||
BCi = ROL(Eka, 3);
|
||||
Eme ^= De;
|
||||
BCo = ROL(Eme, 45);
|
||||
Esi ^= Di;
|
||||
BCu = ROL(Esi, 61);
|
||||
Aga = BCa ^((~BCe)& BCi );
|
||||
Age = BCe ^((~BCi)& BCo );
|
||||
Agi = BCi ^((~BCo)& BCu );
|
||||
Ago = BCo ^((~BCu)& BCa );
|
||||
Agu = BCu ^((~BCa)& BCe );
|
||||
Ebe ^= De;
|
||||
BCa = ROL(Ebe, 1);
|
||||
Egi ^= Di;
|
||||
BCe = ROL(Egi, 6);
|
||||
Eko ^= Do;
|
||||
BCi = ROL(Eko, 25);
|
||||
Emu ^= Du;
|
||||
BCo = ROL(Emu, 8);
|
||||
Esa ^= Da;
|
||||
BCu = ROL(Esa, 18);
|
||||
Aka = BCa ^ ((~BCe) & BCi);
|
||||
Ake = BCe ^ ((~BCi) & BCo);
|
||||
Aki = BCi ^ ((~BCo) & BCu);
|
||||
Ako = BCo ^ ((~BCu) & BCa);
|
||||
Aku = BCu ^ ((~BCa) & BCe);
|
||||
|
||||
Ebe ^= De;
|
||||
BCa = ROL(Ebe, 1);
|
||||
Egi ^= Di;
|
||||
BCe = ROL(Egi, 6);
|
||||
Eko ^= Do;
|
||||
BCi = ROL(Eko, 25);
|
||||
Emu ^= Du;
|
||||
BCo = ROL(Emu, 8);
|
||||
Esa ^= Da;
|
||||
BCu = ROL(Esa, 18);
|
||||
Aka = BCa ^((~BCe)& BCi );
|
||||
Ake = BCe ^((~BCi)& BCo );
|
||||
Aki = BCi ^((~BCo)& BCu );
|
||||
Ako = BCo ^((~BCu)& BCa );
|
||||
Aku = BCu ^((~BCa)& BCe );
|
||||
Ebu ^= Du;
|
||||
BCa = ROL(Ebu, 27);
|
||||
Ega ^= Da;
|
||||
BCe = ROL(Ega, 36);
|
||||
Eke ^= De;
|
||||
BCi = ROL(Eke, 10);
|
||||
Emi ^= Di;
|
||||
BCo = ROL(Emi, 15);
|
||||
Eso ^= Do;
|
||||
BCu = ROL(Eso, 56);
|
||||
Ama = BCa ^ ((~BCe) & BCi);
|
||||
Ame = BCe ^ ((~BCi) & BCo);
|
||||
Ami = BCi ^ ((~BCo) & BCu);
|
||||
Amo = BCo ^ ((~BCu) & BCa);
|
||||
Amu = BCu ^ ((~BCa) & BCe);
|
||||
|
||||
Ebu ^= Du;
|
||||
BCa = ROL(Ebu, 27);
|
||||
Ega ^= Da;
|
||||
BCe = ROL(Ega, 36);
|
||||
Eke ^= De;
|
||||
BCi = ROL(Eke, 10);
|
||||
Emi ^= Di;
|
||||
BCo = ROL(Emi, 15);
|
||||
Eso ^= Do;
|
||||
BCu = ROL(Eso, 56);
|
||||
Ama = BCa ^((~BCe)& BCi );
|
||||
Ame = BCe ^((~BCi)& BCo );
|
||||
Ami = BCi ^((~BCo)& BCu );
|
||||
Amo = BCo ^((~BCu)& BCa );
|
||||
Amu = BCu ^((~BCa)& BCe );
|
||||
Ebi ^= Di;
|
||||
BCa = ROL(Ebi, 62);
|
||||
Ego ^= Do;
|
||||
BCe = ROL(Ego, 55);
|
||||
Eku ^= Du;
|
||||
BCi = ROL(Eku, 39);
|
||||
Ema ^= Da;
|
||||
BCo = ROL(Ema, 41);
|
||||
Ese ^= De;
|
||||
BCu = ROL(Ese, 2);
|
||||
Asa = BCa ^ ((~BCe) & BCi);
|
||||
Ase = BCe ^ ((~BCi) & BCo);
|
||||
Asi = BCi ^ ((~BCo) & BCu);
|
||||
Aso = BCo ^ ((~BCu) & BCa);
|
||||
Asu = BCu ^ ((~BCa) & BCe);
|
||||
}
|
||||
|
||||
Ebi ^= Di;
|
||||
BCa = ROL(Ebi, 62);
|
||||
Ego ^= Do;
|
||||
BCe = ROL(Ego, 55);
|
||||
Eku ^= Du;
|
||||
BCi = ROL(Eku, 39);
|
||||
Ema ^= Da;
|
||||
BCo = ROL(Ema, 41);
|
||||
Ese ^= De;
|
||||
BCu = ROL(Ese, 2);
|
||||
Asa = BCa ^((~BCe)& BCi );
|
||||
Ase = BCe ^((~BCi)& BCo );
|
||||
Asi = BCi ^((~BCo)& BCu );
|
||||
Aso = BCo ^((~BCu)& BCa );
|
||||
Asu = BCu ^((~BCa)& BCe );
|
||||
}
|
||||
//copyToState(state, A)
|
||||
state[0] = Aba;
|
||||
state[1] = Abe;
|
||||
state[2] = Abi;
|
||||
state[3] = Abo;
|
||||
state[4] = Abu;
|
||||
state[5] = Aga;
|
||||
state[6] = Age;
|
||||
state[7] = Agi;
|
||||
state[8] = Ago;
|
||||
state[9] = Agu;
|
||||
state[10] = Aka;
|
||||
state[11] = Ake;
|
||||
state[12] = Aki;
|
||||
state[13] = Ako;
|
||||
state[14] = Aku;
|
||||
state[15] = Ama;
|
||||
state[16] = Ame;
|
||||
state[17] = Ami;
|
||||
state[18] = Amo;
|
||||
state[19] = Amu;
|
||||
state[20] = Asa;
|
||||
state[21] = Ase;
|
||||
state[22] = Asi;
|
||||
state[23] = Aso;
|
||||
state[24] = Asu;
|
||||
|
||||
//copyToState(state, A)
|
||||
state[ 0] = Aba;
|
||||
state[ 1] = Abe;
|
||||
state[ 2] = Abi;
|
||||
state[ 3] = Abo;
|
||||
state[ 4] = Abu;
|
||||
state[ 5] = Aga;
|
||||
state[ 6] = Age;
|
||||
state[ 7] = Agi;
|
||||
state[ 8] = Ago;
|
||||
state[ 9] = Agu;
|
||||
state[10] = Aka;
|
||||
state[11] = Ake;
|
||||
state[12] = Aki;
|
||||
state[13] = Ako;
|
||||
state[14] = Aku;
|
||||
state[15] = Ama;
|
||||
state[16] = Ame;
|
||||
state[17] = Ami;
|
||||
state[18] = Amo;
|
||||
state[19] = Amu;
|
||||
state[20] = Asa;
|
||||
state[21] = Ase;
|
||||
state[22] = Asi;
|
||||
state[23] = Aso;
|
||||
state[24] = Asu;
|
||||
|
||||
#undef round
|
||||
#undef round
|
||||
}
|
||||
|
||||
#include <string.h>
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
static void keccak_absorb(uint64_t *s, unsigned int r, const unsigned char *m, unsigned long long int mlen, unsigned char p) {
|
||||
unsigned long long i;
|
||||
unsigned char t[200];
|
||||
|
||||
static void keccak_absorb(uint64_t *s, unsigned int r, const unsigned char *m, unsigned long long int mlen, unsigned char p)
|
||||
{
|
||||
unsigned long long i;
|
||||
unsigned char t[200];
|
||||
while (mlen >= r) {
|
||||
for (i = 0; i < r / 8; ++i)
|
||||
s[i] ^= load64(m + 8 * i);
|
||||
|
||||
while (mlen >= r)
|
||||
{
|
||||
for (i = 0; i < r / 8; ++i)
|
||||
s[i] ^= load64(m + 8 * i);
|
||||
KeccakF1600_StatePermute(s);
|
||||
mlen -= r;
|
||||
m += r;
|
||||
}
|
||||
|
||||
KeccakF1600_StatePermute(s);
|
||||
mlen -= r;
|
||||
m += r;
|
||||
}
|
||||
|
||||
for (i = 0; i < r; ++i)
|
||||
t[i] = 0;
|
||||
for (i = 0; i < mlen; ++i)
|
||||
t[i] = m[i];
|
||||
t[i] = p;
|
||||
t[r - 1] |= 128;
|
||||
for (i = 0; i < r / 8; ++i)
|
||||
s[i] ^= load64(t + 8 * i);
|
||||
for (i = 0; i < r; ++i)
|
||||
t[i] = 0;
|
||||
for (i = 0; i < mlen; ++i)
|
||||
t[i] = m[i];
|
||||
t[i] = p;
|
||||
t[r - 1] |= 128;
|
||||
for (i = 0; i < r / 8; ++i)
|
||||
s[i] ^= load64(t + 8 * i);
|
||||
}
|
||||
|
||||
static void keccak_squeezeblocks(unsigned char *h, unsigned long long int nblocks, uint64_t *s, unsigned int r) {
|
||||
unsigned int i;
|
||||
|
||||
static void keccak_squeezeblocks(unsigned char *h, unsigned long long int nblocks, uint64_t *s, unsigned int r)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
while(nblocks > 0)
|
||||
{
|
||||
KeccakF1600_StatePermute(s);
|
||||
for (i = 0; i < (r>>3); i++)
|
||||
{
|
||||
store64(h+8*i, s[i]);
|
||||
}
|
||||
h += r;
|
||||
nblocks--;
|
||||
}
|
||||
while (nblocks > 0) {
|
||||
KeccakF1600_StatePermute(s);
|
||||
for (i = 0; i < (r >> 3); i++) {
|
||||
store64(h + 8 * i, s[i]);
|
||||
}
|
||||
h += r;
|
||||
nblocks--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/********** SHAKE128 ***********/
|
||||
|
||||
void shake128_absorb(uint64_t *s, const unsigned char *input, unsigned int inputByteLen)
|
||||
{
|
||||
void shake128_absorb(uint64_t *s, const unsigned char *input, unsigned int inputByteLen) {
|
||||
keccak_absorb(s, SHAKE128_RATE, input, inputByteLen, 0x1F);
|
||||
}
|
||||
|
||||
|
||||
void shake128_squeezeblocks(unsigned char *output, unsigned long long nblocks, uint64_t *s)
|
||||
{
|
||||
void shake128_squeezeblocks(unsigned char *output, unsigned long long nblocks, uint64_t *s) {
|
||||
keccak_squeezeblocks(output, nblocks, s, SHAKE128_RATE);
|
||||
}
|
||||
|
||||
void shake128(unsigned char *output, unsigned long long outlen, const unsigned char *input, unsigned long long inlen) {
|
||||
uint64_t s[25] = {0};
|
||||
unsigned char t[SHAKE128_RATE];
|
||||
unsigned long long nblocks = outlen / SHAKE128_RATE;
|
||||
size_t i;
|
||||
|
||||
void shake128(unsigned char *output, unsigned long long outlen, const unsigned char *input, unsigned long long inlen)
|
||||
{
|
||||
uint64_t s[25] = {0};
|
||||
unsigned char t[SHAKE128_RATE];
|
||||
unsigned long long nblocks = outlen/SHAKE128_RATE;
|
||||
size_t i;
|
||||
/* Absorb input */
|
||||
keccak_absorb(s, SHAKE128_RATE, input, inlen, 0x1F);
|
||||
|
||||
/* Absorb input */
|
||||
keccak_absorb(s, SHAKE128_RATE, input, inlen, 0x1F);
|
||||
/* Squeeze output */
|
||||
keccak_squeezeblocks(output, nblocks, s, SHAKE128_RATE);
|
||||
|
||||
/* Squeeze output */
|
||||
keccak_squeezeblocks(output, nblocks, s, SHAKE128_RATE);
|
||||
output += nblocks * SHAKE128_RATE;
|
||||
outlen -= nblocks * SHAKE128_RATE;
|
||||
|
||||
output += nblocks*SHAKE128_RATE;
|
||||
outlen -= nblocks*SHAKE128_RATE;
|
||||
|
||||
if (outlen)
|
||||
{
|
||||
keccak_squeezeblocks(t, 1, s, SHAKE128_RATE);
|
||||
for (i = 0; i < outlen; i++)
|
||||
output[i] = t[i];
|
||||
}
|
||||
if (outlen) {
|
||||
keccak_squeezeblocks(t, 1, s, SHAKE128_RATE);
|
||||
for (i = 0; i < outlen; i++)
|
||||
output[i] = t[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/********** cSHAKE128 ***********/
|
||||
|
||||
void cshake128_simple_absorb(uint64_t s[25], uint16_t cstm, const unsigned char *in, unsigned long long inlen)
|
||||
{
|
||||
unsigned char *sep = (unsigned char*)s;
|
||||
unsigned int i;
|
||||
void cshake128_simple_absorb(uint64_t s[25], uint16_t cstm, const unsigned char *in, unsigned long long inlen) {
|
||||
unsigned char *sep = (unsigned char *) s;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < 25; i++)
|
||||
s[i] = 0;
|
||||
for (i = 0; i < 25; i++)
|
||||
s[i] = 0;
|
||||
|
||||
/* Absorb customization (domain-separation) string */
|
||||
sep[0] = 0x01;
|
||||
sep[1] = 0xa8;
|
||||
sep[2] = 0x01;
|
||||
sep[3] = 0x00;
|
||||
sep[4] = 0x01;
|
||||
sep[5] = 16; // fixed bitlen of cstm
|
||||
sep[6] = cstm & 0xff;
|
||||
sep[7] = cstm >> 8;
|
||||
/* Absorb customization (domain-separation) string */
|
||||
sep[0] = 0x01;
|
||||
sep[1] = 0xa8;
|
||||
sep[2] = 0x01;
|
||||
sep[3] = 0x00;
|
||||
sep[4] = 0x01;
|
||||
sep[5] = 16; // fixed bitlen of cstm
|
||||
sep[6] = cstm & 0xff;
|
||||
sep[7] = cstm >> 8;
|
||||
|
||||
KeccakF1600_StatePermute(s);
|
||||
KeccakF1600_StatePermute(s);
|
||||
|
||||
/* Absorb input */
|
||||
keccak_absorb(s, SHAKE128_RATE, in, inlen, 0x04);
|
||||
/* Absorb input */
|
||||
keccak_absorb(s, SHAKE128_RATE, in, inlen, 0x04);
|
||||
}
|
||||
|
||||
|
||||
void cshake128_simple_squeezeblocks(unsigned char *output, unsigned long long nblocks, uint64_t *s)
|
||||
{
|
||||
keccak_squeezeblocks(output, nblocks, s, SHAKE128_RATE);
|
||||
void cshake128_simple_squeezeblocks(unsigned char *output, unsigned long long nblocks, uint64_t *s) {
|
||||
keccak_squeezeblocks(output, nblocks, s, SHAKE128_RATE);
|
||||
}
|
||||
|
||||
void cshake128_simple(unsigned char *output, unsigned long long outlen, uint16_t cstm, const unsigned char *in, unsigned long long inlen) {
|
||||
uint64_t s[25];
|
||||
unsigned char t[SHAKE128_RATE];
|
||||
unsigned int i;
|
||||
|
||||
void cshake128_simple(unsigned char *output, unsigned long long outlen, uint16_t cstm, const unsigned char *in, unsigned long long inlen)
|
||||
{
|
||||
uint64_t s[25];
|
||||
unsigned char t[SHAKE128_RATE];
|
||||
unsigned int i;
|
||||
cshake128_simple_absorb(s, cstm, in, inlen);
|
||||
|
||||
cshake128_simple_absorb(s, cstm, in, inlen);
|
||||
/* Squeeze output */
|
||||
keccak_squeezeblocks(output, outlen / SHAKE128_RATE, s, SHAKE128_RATE);
|
||||
output += (outlen / SHAKE128_RATE) * SHAKE128_RATE;
|
||||
|
||||
/* Squeeze output */
|
||||
keccak_squeezeblocks(output, outlen/SHAKE128_RATE, s, SHAKE128_RATE);
|
||||
output += (outlen/SHAKE128_RATE)*SHAKE128_RATE;
|
||||
|
||||
if (outlen%SHAKE128_RATE)
|
||||
{
|
||||
keccak_squeezeblocks(t, 1, s, SHAKE128_RATE);
|
||||
for (i = 0; i < outlen%SHAKE128_RATE; i++)
|
||||
output[i] = t[i];
|
||||
}
|
||||
if (outlen % SHAKE128_RATE) {
|
||||
keccak_squeezeblocks(t, 1, s, SHAKE128_RATE);
|
||||
for (i = 0; i < outlen % SHAKE128_RATE; i++)
|
||||
output[i] = t[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/********** SHAKE256 ***********/
|
||||
|
||||
void shake256_absorb(uint64_t *s, const unsigned char *input, unsigned int inputByteLen)
|
||||
{
|
||||
void shake256_absorb(uint64_t *s, const unsigned char *input, unsigned int inputByteLen) {
|
||||
keccak_absorb(s, SHAKE256_RATE, input, inputByteLen, 0x1F);
|
||||
}
|
||||
|
||||
|
||||
void shake256_squeezeblocks(unsigned char *output, unsigned long long nblocks, uint64_t *s)
|
||||
{
|
||||
void shake256_squeezeblocks(unsigned char *output, unsigned long long nblocks, uint64_t *s) {
|
||||
keccak_squeezeblocks(output, nblocks, s, SHAKE256_RATE);
|
||||
}
|
||||
|
||||
void shake256(unsigned char *output, unsigned long long outlen, const unsigned char *input, unsigned long long inlen) {
|
||||
uint64_t s[25];
|
||||
unsigned char t[SHAKE256_RATE];
|
||||
unsigned long long nblocks = outlen / SHAKE256_RATE;
|
||||
size_t i;
|
||||
|
||||
void shake256(unsigned char *output, unsigned long long outlen, const unsigned char *input, unsigned long long inlen)
|
||||
{
|
||||
uint64_t s[25];
|
||||
unsigned char t[SHAKE256_RATE];
|
||||
unsigned long long nblocks = outlen/SHAKE256_RATE;
|
||||
size_t i;
|
||||
for (i = 0; i < 25; ++i)
|
||||
s[i] = 0;
|
||||
|
||||
for (i = 0; i < 25; ++i)
|
||||
s[i] = 0;
|
||||
/* Absorb input */
|
||||
keccak_absorb(s, SHAKE256_RATE, input, inlen, 0x1F);
|
||||
|
||||
/* Absorb input */
|
||||
keccak_absorb(s, SHAKE256_RATE, input, inlen, 0x1F);
|
||||
/* Squeeze output */
|
||||
keccak_squeezeblocks(output, nblocks, s, SHAKE256_RATE);
|
||||
|
||||
/* Squeeze output */
|
||||
keccak_squeezeblocks(output, nblocks, s, SHAKE256_RATE);
|
||||
output += nblocks * SHAKE256_RATE;
|
||||
outlen -= nblocks * SHAKE256_RATE;
|
||||
|
||||
output += nblocks*SHAKE256_RATE;
|
||||
outlen -= nblocks*SHAKE256_RATE;
|
||||
|
||||
if (outlen)
|
||||
{
|
||||
keccak_squeezeblocks(t, 1, s, SHAKE256_RATE);
|
||||
for (i = 0; i < outlen; i++)
|
||||
output[i] = t[i];
|
||||
}
|
||||
if (outlen) {
|
||||
keccak_squeezeblocks(t, 1, s, SHAKE256_RATE);
|
||||
for (i = 0; i < outlen; i++)
|
||||
output[i] = t[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/********** cSHAKE256 ***********/
|
||||
|
||||
void cshake256_simple_absorb(uint64_t s[25], uint16_t cstm, const unsigned char *in, unsigned long long inlen)
|
||||
{
|
||||
unsigned char *sep = (unsigned char*)s;
|
||||
unsigned int i;
|
||||
void cshake256_simple_absorb(uint64_t s[25], uint16_t cstm, const unsigned char *in, unsigned long long inlen) {
|
||||
unsigned char *sep = (unsigned char *) s;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < 25; i++)
|
||||
s[i] = 0;
|
||||
for (i = 0; i < 25; i++)
|
||||
s[i] = 0;
|
||||
|
||||
/* Absorb customization (domain-separation) string */
|
||||
sep[0] = 0x01;
|
||||
sep[1] = 0x88;
|
||||
sep[2] = 0x01;
|
||||
sep[3] = 0x00;
|
||||
sep[4] = 0x01;
|
||||
sep[5] = 16; // fixed bitlen of cstm
|
||||
sep[6] = cstm & 0xff;
|
||||
sep[7] = cstm >> 8;
|
||||
/* Absorb customization (domain-separation) string */
|
||||
sep[0] = 0x01;
|
||||
sep[1] = 0x88;
|
||||
sep[2] = 0x01;
|
||||
sep[3] = 0x00;
|
||||
sep[4] = 0x01;
|
||||
sep[5] = 16; // fixed bitlen of cstm
|
||||
sep[6] = cstm & 0xff;
|
||||
sep[7] = cstm >> 8;
|
||||
|
||||
KeccakF1600_StatePermute(s);
|
||||
KeccakF1600_StatePermute(s);
|
||||
|
||||
/* Absorb input */
|
||||
keccak_absorb(s, SHAKE256_RATE, in, inlen, 0x04);
|
||||
/* Absorb input */
|
||||
keccak_absorb(s, SHAKE256_RATE, in, inlen, 0x04);
|
||||
}
|
||||
|
||||
|
||||
void cshake256_simple_squeezeblocks(unsigned char *output, unsigned long long nblocks, uint64_t *s)
|
||||
{
|
||||
keccak_squeezeblocks(output, nblocks, s, SHAKE256_RATE);
|
||||
void cshake256_simple_squeezeblocks(unsigned char *output, unsigned long long nblocks, uint64_t *s) {
|
||||
keccak_squeezeblocks(output, nblocks, s, SHAKE256_RATE);
|
||||
}
|
||||
|
||||
void cshake256_simple(unsigned char *output, unsigned long long outlen, uint16_t cstm, const unsigned char *in, unsigned long long inlen) {
|
||||
uint64_t s[25];
|
||||
unsigned char t[SHAKE256_RATE];
|
||||
unsigned int i;
|
||||
|
||||
void cshake256_simple(unsigned char *output, unsigned long long outlen, uint16_t cstm, const unsigned char *in, unsigned long long inlen)
|
||||
{
|
||||
uint64_t s[25];
|
||||
unsigned char t[SHAKE256_RATE];
|
||||
unsigned int i;
|
||||
cshake256_simple_absorb(s, cstm, in, inlen);
|
||||
|
||||
cshake256_simple_absorb(s, cstm, in, inlen);
|
||||
/* Squeeze output */
|
||||
keccak_squeezeblocks(output, outlen / SHAKE256_RATE, s, SHAKE256_RATE);
|
||||
output += (outlen / SHAKE256_RATE) * SHAKE256_RATE;
|
||||
|
||||
/* Squeeze output */
|
||||
keccak_squeezeblocks(output, outlen/SHAKE256_RATE, s, SHAKE256_RATE);
|
||||
output += (outlen/SHAKE256_RATE)*SHAKE256_RATE;
|
||||
|
||||
if(outlen%SHAKE256_RATE)
|
||||
{
|
||||
keccak_squeezeblocks(t, 1, s, SHAKE256_RATE);
|
||||
for (i = 0; i < outlen%SHAKE256_RATE; i++)
|
||||
output[i] = t[i];
|
||||
}
|
||||
if (outlen % SHAKE256_RATE) {
|
||||
keccak_squeezeblocks(t, 1, s, SHAKE256_RATE);
|
||||
for (i = 0; i < outlen % SHAKE256_RATE; i++)
|
||||
output[i] = t[i];
|
||||
}
|
||||
}
|
||||
@ -3,13 +3,12 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#define SHAKE128_RATE 168
|
||||
#define SHAKE256_RATE 136
|
||||
|
||||
void shake128_absorb(uint64_t *s, const unsigned char *input, unsigned int inputByteLen);
|
||||
void shake128_squeezeblocks(unsigned char *output, unsigned long long nblocks, uint64_t *s);
|
||||
void shake128(unsigned char *output, unsigned long long outlen, const unsigned char *input, unsigned long long inlen);
|
||||
void shake128(unsigned char *output, unsigned long long outlen, const unsigned char *input, unsigned long long inlen);
|
||||
|
||||
void cshake128_simple_absorb(uint64_t *s, uint16_t cstm, const unsigned char *in, unsigned long long inlen);
|
||||
void cshake128_simple_squeezeblocks(unsigned char *output, unsigned long long nblocks, uint64_t *s);
|
||||
@ -17,11 +16,10 @@ void cshake128_simple(unsigned char *output, unsigned long long outlen, uint16_t
|
||||
|
||||
void shake256_absorb(uint64_t *s, const unsigned char *input, unsigned int inputByteLen);
|
||||
void shake256_squeezeblocks(unsigned char *output, unsigned long long nblocks, uint64_t *s);
|
||||
void shake256(unsigned char *output, unsigned long long outlen, const unsigned char *input, unsigned long long inlen);
|
||||
void shake256(unsigned char *output, unsigned long long outlen, const unsigned char *input, unsigned long long inlen);
|
||||
|
||||
void cshake256_simple_absorb(uint64_t *s, uint16_t cstm, const unsigned char *in, unsigned long long inlen);
|
||||
void cshake256_simple_squeezeblocks(unsigned char *output, unsigned long long nblocks, uint64_t *s);
|
||||
void cshake256_simple(unsigned char *output, unsigned long long outlen, uint16_t cstm, const unsigned char *in, unsigned long long inlen);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@ -4,327 +4,309 @@
|
||||
* Abstract: ephemeral supersingular isogeny Diffie-Hellman key exchange (SIDH)
|
||||
*********************************************************************************************/
|
||||
|
||||
static void clear_words(void* mem, digit_t nwords)
|
||||
{ // Clear digits from memory. "nwords" indicates the number of digits to be zeroed.
|
||||
// This function uses the volatile type qualifier to inform the compiler not to optimize out the memory clearing.
|
||||
unsigned int i;
|
||||
volatile digit_t *v = mem;
|
||||
static void clear_words(void *mem, digit_t nwords) { // Clear digits from memory. "nwords" indicates the number of digits to be zeroed.
|
||||
// This function uses the volatile type qualifier to inform the compiler not to optimize out the memory clearing.
|
||||
unsigned int i;
|
||||
volatile digit_t *v = mem;
|
||||
|
||||
for (i = 0; i < nwords; i++) {
|
||||
v[i] = 0;
|
||||
}
|
||||
for (i = 0; i < nwords; i++) {
|
||||
v[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void init_basis(digit_t *gen, f2elm_t XP, f2elm_t XQ, f2elm_t XR) { // Initialization of basis points
|
||||
|
||||
static void init_basis(digit_t *gen, f2elm_t XP, f2elm_t XQ, f2elm_t XR)
|
||||
{ // Initialization of basis points
|
||||
|
||||
fpcopy(gen, XP[0]);
|
||||
fpcopy(gen + NWORDS_FIELD, XP[1]);
|
||||
fpcopy(gen + 2*NWORDS_FIELD, XQ[0]);
|
||||
fpzero(XQ[1]);
|
||||
fpcopy(gen + 3*NWORDS_FIELD, XR[0]);
|
||||
fpcopy(gen + 4*NWORDS_FIELD, XR[1]);
|
||||
fpcopy(gen, XP[0]);
|
||||
fpcopy(gen + NWORDS_FIELD, XP[1]);
|
||||
fpcopy(gen + 2 * NWORDS_FIELD, XQ[0]);
|
||||
fpzero(XQ[1]);
|
||||
fpcopy(gen + 3 * NWORDS_FIELD, XR[0]);
|
||||
fpcopy(gen + 4 * NWORDS_FIELD, XR[1]);
|
||||
}
|
||||
|
||||
static void fp2_encode(const f2elm_t x, unsigned char *enc) { // Conversion of GF(p^2) element from Montgomery to standard representation, and encoding by removing leading 0 bytes
|
||||
unsigned int i;
|
||||
f2elm_t t;
|
||||
|
||||
static void fp2_encode(const f2elm_t x, unsigned char *enc)
|
||||
{ // Conversion of GF(p^2) element from Montgomery to standard representation, and encoding by removing leading 0 bytes
|
||||
unsigned int i;
|
||||
f2elm_t t;
|
||||
|
||||
from_fp2mont(x, t);
|
||||
for (i = 0; i < FP2_ENCODED_BYTES / 2; i++) {
|
||||
enc[i] = ((unsigned char*)t)[i];
|
||||
enc[i + FP2_ENCODED_BYTES / 2] = ((unsigned char*)t)[i + MAXBITS_FIELD / 8];
|
||||
}
|
||||
from_fp2mont(x, t);
|
||||
for (i = 0; i < FP2_ENCODED_BYTES / 2; i++) {
|
||||
enc[i] = ((unsigned char *) t)[i];
|
||||
enc[i + FP2_ENCODED_BYTES / 2] = ((unsigned char *) t)[i + MAXBITS_FIELD / 8];
|
||||
}
|
||||
}
|
||||
|
||||
static void fp2_decode(const unsigned char *enc, f2elm_t x) { // Parse byte sequence back into GF(p^2) element, and conversion to Montgomery representation
|
||||
unsigned int i;
|
||||
|
||||
static void fp2_decode(const unsigned char *enc, f2elm_t x)
|
||||
{ // Parse byte sequence back into GF(p^2) element, and conversion to Montgomery representation
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < 2*(MAXBITS_FIELD / 8); i++) ((unsigned char *)x)[i] = 0;
|
||||
for (i = 0; i < FP2_ENCODED_BYTES / 2; i++) {
|
||||
((unsigned char*)x)[i] = enc[i];
|
||||
((unsigned char*)x)[i + MAXBITS_FIELD / 8] = enc[i + FP2_ENCODED_BYTES / 2];
|
||||
}
|
||||
to_fp2mont(x, x);
|
||||
for (i = 0; i < 2 * (MAXBITS_FIELD / 8); i++)
|
||||
((unsigned char *) x)[i] = 0;
|
||||
for (i = 0; i < FP2_ENCODED_BYTES / 2; i++) {
|
||||
((unsigned char *) x)[i] = enc[i];
|
||||
((unsigned char *) x)[i + MAXBITS_FIELD / 8] = enc[i + FP2_ENCODED_BYTES / 2];
|
||||
}
|
||||
to_fp2mont(x, x);
|
||||
}
|
||||
|
||||
void random_mod_order_A(unsigned char *random_digits, OQS_RAND *rand) { // Generation of Alice's secret key
|
||||
// Outputs random value in [0, 2^eA - 1]
|
||||
unsigned long long nbytes = NBITS_TO_NBYTES(OALICE_BITS);
|
||||
|
||||
void random_mod_order_A(unsigned char* random_digits, OQS_RAND* rand)
|
||||
{ // Generation of Alice's secret key
|
||||
// Outputs random value in [0, 2^eA - 1]
|
||||
unsigned long long nbytes = NBITS_TO_NBYTES(OALICE_BITS);
|
||||
|
||||
clear_words((void*)random_digits, MAXWORDS_ORDER);
|
||||
OQS_RAND_n(rand, random_digits, nbytes);
|
||||
random_digits[nbytes-1] &= MASK_ALICE; // Masking last byte
|
||||
clear_words((void *) random_digits, MAXWORDS_ORDER);
|
||||
OQS_RAND_n(rand, random_digits, nbytes);
|
||||
random_digits[nbytes - 1] &= MASK_ALICE; // Masking last byte
|
||||
}
|
||||
|
||||
void random_mod_order_B(unsigned char *random_digits, OQS_RAND *rand) { // Generation of Bob's secret key
|
||||
// Outputs random value in [0, 2^Floor(Log(2, oB)) - 1]
|
||||
unsigned long long nbytes = NBITS_TO_NBYTES(OBOB_BITS - 1);
|
||||
|
||||
void random_mod_order_B(unsigned char* random_digits, OQS_RAND* rand)
|
||||
{ // Generation of Bob's secret key
|
||||
// Outputs random value in [0, 2^Floor(Log(2, oB)) - 1]
|
||||
unsigned long long nbytes = NBITS_TO_NBYTES(OBOB_BITS-1);
|
||||
|
||||
clear_words((void*)random_digits, MAXWORDS_ORDER);
|
||||
OQS_RAND_n(rand, random_digits, nbytes);
|
||||
random_digits[nbytes-1] &= MASK_BOB; // Masking last byte
|
||||
clear_words((void *) random_digits, MAXWORDS_ORDER);
|
||||
OQS_RAND_n(rand, random_digits, nbytes);
|
||||
random_digits[nbytes - 1] &= MASK_BOB; // Masking last byte
|
||||
}
|
||||
|
||||
int EphemeralKeyGeneration_A(const unsigned char *PrivateKeyA, unsigned char *PublicKeyA, OQS_RAND *rand) { // Alice's ephemeral public key generation
|
||||
// Input: a private key PrivateKeyA in the range [0, 2^eA - 1].
|
||||
// Output: the public key PublicKeyA consisting of 3 elements in GF(p^2) which are encoded by removing leading 0 bytes.
|
||||
point_proj_t R, phiP = {0}, phiQ = {0}, phiR = {0}, pts[MAX_INT_POINTS_ALICE];
|
||||
f2elm_t XPA, XQA, XRA, coeff[3], A24plus = {0}, C24 = {0}, A = {0};
|
||||
unsigned int i, row, m, index = 0, pts_index[MAX_INT_POINTS_ALICE], npts = 0, ii = 0;
|
||||
|
||||
int EphemeralKeyGeneration_A(const unsigned char* PrivateKeyA, unsigned char* PublicKeyA, OQS_RAND *rand)
|
||||
{ // Alice's ephemeral public key generation
|
||||
// Input: a private key PrivateKeyA in the range [0, 2^eA - 1].
|
||||
// Output: the public key PublicKeyA consisting of 3 elements in GF(p^2) which are encoded by removing leading 0 bytes.
|
||||
point_proj_t R, phiP = {0}, phiQ = {0}, phiR = {0}, pts[MAX_INT_POINTS_ALICE];
|
||||
f2elm_t XPA, XQA, XRA, coeff[3], A24plus = {0}, C24 = {0}, A = {0};
|
||||
unsigned int i, row, m, index = 0, pts_index[MAX_INT_POINTS_ALICE], npts = 0, ii = 0;
|
||||
// Initialize basis points
|
||||
init_basis((digit_t *) A_gen, XPA, XQA, XRA);
|
||||
init_basis((digit_t *) B_gen, phiP->X, phiQ->X, phiR->X);
|
||||
fpcopy((digit_t *) &Montgomery_one, (phiP->Z)[0]);
|
||||
fpcopy((digit_t *) &Montgomery_one, (phiQ->Z)[0]);
|
||||
fpcopy((digit_t *) &Montgomery_one, (phiR->Z)[0]);
|
||||
|
||||
// Initialize basis points
|
||||
init_basis((digit_t*)A_gen, XPA, XQA, XRA);
|
||||
init_basis((digit_t*)B_gen, phiP->X, phiQ->X, phiR->X);
|
||||
fpcopy((digit_t*)&Montgomery_one, (phiP->Z)[0]);
|
||||
fpcopy((digit_t*)&Montgomery_one, (phiQ->Z)[0]);
|
||||
fpcopy((digit_t*)&Montgomery_one, (phiR->Z)[0]);
|
||||
// Initialize constants
|
||||
fpcopy((digit_t *) &Montgomery_one, A24plus[0]);
|
||||
fp2add(A24plus, A24plus, C24);
|
||||
|
||||
// Initialize constants
|
||||
fpcopy((digit_t*)&Montgomery_one, A24plus[0]);
|
||||
fp2add(A24plus, A24plus, C24);
|
||||
// Retrieve kernel point
|
||||
LADDER3PT(XPA, XQA, XRA, (digit_t *) PrivateKeyA, ALICE, R, A);
|
||||
|
||||
// Retrieve kernel point
|
||||
LADDER3PT(XPA, XQA, XRA, (digit_t*)PrivateKeyA, ALICE, R, A);
|
||||
// Traverse tree
|
||||
index = 0;
|
||||
for (row = 1; row < MAX_Alice; row++) {
|
||||
while (index < MAX_Alice - row) {
|
||||
fp2copy(R->X, pts[npts]->X);
|
||||
fp2copy(R->Z, pts[npts]->Z);
|
||||
pts_index[npts++] = index;
|
||||
m = strat_Alice[ii++];
|
||||
xDBLe(R, R, A24plus, C24, (int) (2 * m));
|
||||
index += m;
|
||||
}
|
||||
get_4_isog(R, A24plus, C24, coeff);
|
||||
|
||||
// Traverse tree
|
||||
index = 0;
|
||||
for (row = 1; row < MAX_Alice; row++) {
|
||||
while (index < MAX_Alice-row) {
|
||||
fp2copy(R->X, pts[npts]->X);
|
||||
fp2copy(R->Z, pts[npts]->Z);
|
||||
pts_index[npts++] = index;
|
||||
m = strat_Alice[ii++];
|
||||
xDBLe(R, R, A24plus, C24, (int)(2*m));
|
||||
index += m;
|
||||
}
|
||||
get_4_isog(R, A24plus, C24, coeff);
|
||||
for (i = 0; i < npts; i++) {
|
||||
eval_4_isog(pts[i], coeff);
|
||||
}
|
||||
eval_4_isog(phiP, coeff);
|
||||
eval_4_isog(phiQ, coeff);
|
||||
eval_4_isog(phiR, coeff);
|
||||
|
||||
for (i = 0; i < npts; i++) {
|
||||
eval_4_isog(pts[i], coeff);
|
||||
}
|
||||
eval_4_isog(phiP, coeff);
|
||||
eval_4_isog(phiQ, coeff);
|
||||
eval_4_isog(phiR, coeff);
|
||||
fp2copy(pts[npts - 1]->X, R->X);
|
||||
fp2copy(pts[npts - 1]->Z, R->Z);
|
||||
index = pts_index[npts - 1];
|
||||
npts -= 1;
|
||||
}
|
||||
|
||||
fp2copy(pts[npts-1]->X, R->X);
|
||||
fp2copy(pts[npts-1]->Z, R->Z);
|
||||
index = pts_index[npts-1];
|
||||
npts -= 1;
|
||||
}
|
||||
get_4_isog(R, A24plus, C24, coeff);
|
||||
eval_4_isog(phiP, coeff);
|
||||
eval_4_isog(phiQ, coeff);
|
||||
eval_4_isog(phiR, coeff);
|
||||
|
||||
get_4_isog(R, A24plus, C24, coeff);
|
||||
eval_4_isog(phiP, coeff);
|
||||
eval_4_isog(phiQ, coeff);
|
||||
eval_4_isog(phiR, coeff);
|
||||
inv_3_way(phiP->Z, phiQ->Z, phiR->Z);
|
||||
fp2mul_mont(phiP->X, phiP->Z, phiP->X);
|
||||
fp2mul_mont(phiQ->X, phiQ->Z, phiQ->X);
|
||||
fp2mul_mont(phiR->X, phiR->Z, phiR->X);
|
||||
|
||||
inv_3_way(phiP->Z, phiQ->Z, phiR->Z);
|
||||
fp2mul_mont(phiP->X, phiP->Z, phiP->X);
|
||||
fp2mul_mont(phiQ->X, phiQ->Z, phiQ->X);
|
||||
fp2mul_mont(phiR->X, phiR->Z, phiR->X);
|
||||
// Format public key
|
||||
fp2_encode(phiP->X, PublicKeyA);
|
||||
fp2_encode(phiQ->X, PublicKeyA + FP2_ENCODED_BYTES);
|
||||
fp2_encode(phiR->X, PublicKeyA + 2 * FP2_ENCODED_BYTES);
|
||||
|
||||
// Format public key
|
||||
fp2_encode(phiP->X, PublicKeyA);
|
||||
fp2_encode(phiQ->X, PublicKeyA + FP2_ENCODED_BYTES);
|
||||
fp2_encode(phiR->X, PublicKeyA + 2*FP2_ENCODED_BYTES);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EphemeralKeyGeneration_B(const unsigned char *PrivateKeyB, unsigned char *PublicKeyB, OQS_RAND *rand) { // Bob's ephemeral public key generation
|
||||
// Input: a private key PrivateKeyB in the range [0, 2^Floor(Log(2,oB)) - 1].
|
||||
// Output: the public key PublicKeyB consisting of 3 elements in GF(p^2) which are encoded by removing leading 0 bytes.
|
||||
point_proj_t R, phiP = {0}, phiQ = {0}, phiR = {0}, pts[MAX_INT_POINTS_BOB];
|
||||
f2elm_t XPB, XQB, XRB, coeff[3], A24plus = {0}, A24minus = {0}, A = {0};
|
||||
unsigned int i, row, m, index = 0, pts_index[MAX_INT_POINTS_BOB], npts = 0, ii = 0;
|
||||
|
||||
int EphemeralKeyGeneration_B(const unsigned char* PrivateKeyB, unsigned char* PublicKeyB, OQS_RAND *rand)
|
||||
{ // Bob's ephemeral public key generation
|
||||
// Input: a private key PrivateKeyB in the range [0, 2^Floor(Log(2,oB)) - 1].
|
||||
// Output: the public key PublicKeyB consisting of 3 elements in GF(p^2) which are encoded by removing leading 0 bytes.
|
||||
point_proj_t R, phiP = {0}, phiQ = {0}, phiR = {0}, pts[MAX_INT_POINTS_BOB];
|
||||
f2elm_t XPB, XQB, XRB, coeff[3], A24plus = {0}, A24minus = {0}, A = {0};
|
||||
unsigned int i, row, m, index = 0, pts_index[MAX_INT_POINTS_BOB], npts = 0, ii = 0;
|
||||
// Initialize basis points
|
||||
init_basis((digit_t *) B_gen, XPB, XQB, XRB);
|
||||
init_basis((digit_t *) A_gen, phiP->X, phiQ->X, phiR->X);
|
||||
fpcopy((digit_t *) &Montgomery_one, (phiP->Z)[0]);
|
||||
fpcopy((digit_t *) &Montgomery_one, (phiQ->Z)[0]);
|
||||
fpcopy((digit_t *) &Montgomery_one, (phiR->Z)[0]);
|
||||
|
||||
// Initialize basis points
|
||||
init_basis((digit_t*)B_gen, XPB, XQB, XRB);
|
||||
init_basis((digit_t*)A_gen, phiP->X, phiQ->X, phiR->X);
|
||||
fpcopy((digit_t*)&Montgomery_one, (phiP->Z)[0]);
|
||||
fpcopy((digit_t*)&Montgomery_one, (phiQ->Z)[0]);
|
||||
fpcopy((digit_t*)&Montgomery_one, (phiR->Z)[0]);
|
||||
// Initialize constants
|
||||
fpcopy((digit_t *) &Montgomery_one, A24plus[0]);
|
||||
fp2add(A24plus, A24plus, A24plus);
|
||||
fp2copy(A24plus, A24minus);
|
||||
fp2neg(A24minus);
|
||||
|
||||
// Initialize constants
|
||||
fpcopy((digit_t*)&Montgomery_one, A24plus[0]);
|
||||
fp2add(A24plus, A24plus, A24plus);
|
||||
fp2copy(A24plus, A24minus);
|
||||
fp2neg(A24minus);
|
||||
// Retrieve kernel point
|
||||
LADDER3PT(XPB, XQB, XRB, (digit_t *) PrivateKeyB, BOB, R, A);
|
||||
|
||||
// Retrieve kernel point
|
||||
LADDER3PT(XPB, XQB, XRB, (digit_t*)PrivateKeyB, BOB, R, A);
|
||||
// Traverse tree
|
||||
index = 0;
|
||||
for (row = 1; row < MAX_Bob; row++) {
|
||||
while (index < MAX_Bob - row) {
|
||||
fp2copy(R->X, pts[npts]->X);
|
||||
fp2copy(R->Z, pts[npts]->Z);
|
||||
pts_index[npts++] = index;
|
||||
m = strat_Bob[ii++];
|
||||
xTPLe(R, R, A24minus, A24plus, (int) m);
|
||||
index += m;
|
||||
}
|
||||
get_3_isog(R, A24minus, A24plus, coeff);
|
||||
|
||||
// Traverse tree
|
||||
index = 0;
|
||||
for (row = 1; row < MAX_Bob; row++) {
|
||||
while (index < MAX_Bob-row) {
|
||||
fp2copy(R->X, pts[npts]->X);
|
||||
fp2copy(R->Z, pts[npts]->Z);
|
||||
pts_index[npts++] = index;
|
||||
m = strat_Bob[ii++];
|
||||
xTPLe(R, R, A24minus, A24plus, (int)m);
|
||||
index += m;
|
||||
}
|
||||
get_3_isog(R, A24minus, A24plus, coeff);
|
||||
for (i = 0; i < npts; i++) {
|
||||
eval_3_isog(pts[i], coeff);
|
||||
}
|
||||
eval_3_isog(phiP, coeff);
|
||||
eval_3_isog(phiQ, coeff);
|
||||
eval_3_isog(phiR, coeff);
|
||||
|
||||
for (i = 0; i < npts; i++) {
|
||||
eval_3_isog(pts[i], coeff);
|
||||
}
|
||||
eval_3_isog(phiP, coeff);
|
||||
eval_3_isog(phiQ, coeff);
|
||||
eval_3_isog(phiR, coeff);
|
||||
fp2copy(pts[npts - 1]->X, R->X);
|
||||
fp2copy(pts[npts - 1]->Z, R->Z);
|
||||
index = pts_index[npts - 1];
|
||||
npts -= 1;
|
||||
}
|
||||
|
||||
fp2copy(pts[npts-1]->X, R->X);
|
||||
fp2copy(pts[npts-1]->Z, R->Z);
|
||||
index = pts_index[npts-1];
|
||||
npts -= 1;
|
||||
}
|
||||
get_3_isog(R, A24minus, A24plus, coeff);
|
||||
eval_3_isog(phiP, coeff);
|
||||
eval_3_isog(phiQ, coeff);
|
||||
eval_3_isog(phiR, coeff);
|
||||
|
||||
get_3_isog(R, A24minus, A24plus, coeff);
|
||||
eval_3_isog(phiP, coeff);
|
||||
eval_3_isog(phiQ, coeff);
|
||||
eval_3_isog(phiR, coeff);
|
||||
inv_3_way(phiP->Z, phiQ->Z, phiR->Z);
|
||||
fp2mul_mont(phiP->X, phiP->Z, phiP->X);
|
||||
fp2mul_mont(phiQ->X, phiQ->Z, phiQ->X);
|
||||
fp2mul_mont(phiR->X, phiR->Z, phiR->X);
|
||||
|
||||
inv_3_way(phiP->Z, phiQ->Z, phiR->Z);
|
||||
fp2mul_mont(phiP->X, phiP->Z, phiP->X);
|
||||
fp2mul_mont(phiQ->X, phiQ->Z, phiQ->X);
|
||||
fp2mul_mont(phiR->X, phiR->Z, phiR->X);
|
||||
// Format public key
|
||||
fp2_encode(phiP->X, PublicKeyB);
|
||||
fp2_encode(phiQ->X, PublicKeyB + FP2_ENCODED_BYTES);
|
||||
fp2_encode(phiR->X, PublicKeyB + 2 * FP2_ENCODED_BYTES);
|
||||
|
||||
// Format public key
|
||||
fp2_encode(phiP->X, PublicKeyB);
|
||||
fp2_encode(phiQ->X, PublicKeyB + FP2_ENCODED_BYTES);
|
||||
fp2_encode(phiR->X, PublicKeyB + 2*FP2_ENCODED_BYTES);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EphemeralSecretAgreement_A(const unsigned char *PrivateKeyA, const unsigned char *PublicKeyB, unsigned char *SharedSecretA) { // Alice's ephemeral shared secret computation
|
||||
// It produces a shared secret key SharedSecretA using her secret key PrivateKeyA and Bob's public key PublicKeyB
|
||||
// Inputs: Alice's PrivateKeyA is an integer in the range [0, oA-1].
|
||||
// Bob's PublicKeyB consists of 3 elements in GF(p^2) encoded by removing leading 0 bytes.
|
||||
// Output: a shared secret SharedSecretA that consists of one element in GF(p^2) encoded by removing leading 0 bytes.
|
||||
point_proj_t R, pts[MAX_INT_POINTS_ALICE];
|
||||
f2elm_t coeff[3], PKB[3], jinv;
|
||||
f2elm_t A24plus = {0}, C24 = {0}, A = {0};
|
||||
unsigned int i, row, m, index = 0, pts_index[MAX_INT_POINTS_ALICE], npts = 0, ii = 0;
|
||||
|
||||
int EphemeralSecretAgreement_A(const unsigned char* PrivateKeyA, const unsigned char* PublicKeyB, unsigned char* SharedSecretA)
|
||||
{ // Alice's ephemeral shared secret computation
|
||||
// It produces a shared secret key SharedSecretA using her secret key PrivateKeyA and Bob's public key PublicKeyB
|
||||
// Inputs: Alice's PrivateKeyA is an integer in the range [0, oA-1].
|
||||
// Bob's PublicKeyB consists of 3 elements in GF(p^2) encoded by removing leading 0 bytes.
|
||||
// Output: a shared secret SharedSecretA that consists of one element in GF(p^2) encoded by removing leading 0 bytes.
|
||||
point_proj_t R, pts[MAX_INT_POINTS_ALICE];
|
||||
f2elm_t coeff[3], PKB[3], jinv;
|
||||
f2elm_t A24plus = {0}, C24 = {0}, A = {0};
|
||||
unsigned int i, row, m, index = 0, pts_index[MAX_INT_POINTS_ALICE], npts = 0, ii = 0;
|
||||
// Initialize images of Bob's basis
|
||||
fp2_decode(PublicKeyB, PKB[0]);
|
||||
fp2_decode(PublicKeyB + FP2_ENCODED_BYTES, PKB[1]);
|
||||
fp2_decode(PublicKeyB + 2 * FP2_ENCODED_BYTES, PKB[2]);
|
||||
|
||||
// Initialize images of Bob's basis
|
||||
fp2_decode(PublicKeyB, PKB[0]);
|
||||
fp2_decode(PublicKeyB + FP2_ENCODED_BYTES, PKB[1]);
|
||||
fp2_decode(PublicKeyB + 2*FP2_ENCODED_BYTES, PKB[2]);
|
||||
// Initialize constants
|
||||
get_A(PKB[0], PKB[1], PKB[2], A); // TODO: Can return projective A?
|
||||
fpadd((digit_t *) &Montgomery_one, (digit_t *) &Montgomery_one, C24[0]);
|
||||
fp2add(A, C24, A24plus);
|
||||
fpadd(C24[0], C24[0], C24[0]);
|
||||
|
||||
// Initialize constants
|
||||
get_A(PKB[0], PKB[1], PKB[2], A); // TODO: Can return projective A?
|
||||
fpadd((digit_t*)&Montgomery_one, (digit_t*)&Montgomery_one, C24[0]);
|
||||
fp2add(A, C24, A24plus);
|
||||
fpadd(C24[0], C24[0], C24[0]);
|
||||
// Retrieve kernel point
|
||||
LADDER3PT(PKB[0], PKB[1], PKB[2], (digit_t *) PrivateKeyA, ALICE, R, A);
|
||||
|
||||
// Retrieve kernel point
|
||||
LADDER3PT(PKB[0], PKB[1], PKB[2], (digit_t*)PrivateKeyA, ALICE, R, A);
|
||||
// Traverse tree
|
||||
index = 0;
|
||||
for (row = 1; row < MAX_Alice; row++) {
|
||||
while (index < MAX_Alice - row) {
|
||||
fp2copy(R->X, pts[npts]->X);
|
||||
fp2copy(R->Z, pts[npts]->Z);
|
||||
pts_index[npts++] = index;
|
||||
m = strat_Alice[ii++];
|
||||
xDBLe(R, R, A24plus, C24, (int) (2 * m));
|
||||
index += m;
|
||||
}
|
||||
get_4_isog(R, A24plus, C24, coeff);
|
||||
|
||||
// Traverse tree
|
||||
index = 0;
|
||||
for (row = 1; row < MAX_Alice; row++) {
|
||||
while (index < MAX_Alice-row) {
|
||||
fp2copy(R->X, pts[npts]->X);
|
||||
fp2copy(R->Z, pts[npts]->Z);
|
||||
pts_index[npts++] = index;
|
||||
m = strat_Alice[ii++];
|
||||
xDBLe(R, R, A24plus, C24, (int)(2*m));
|
||||
index += m;
|
||||
}
|
||||
get_4_isog(R, A24plus, C24, coeff);
|
||||
for (i = 0; i < npts; i++) {
|
||||
eval_4_isog(pts[i], coeff);
|
||||
}
|
||||
|
||||
for (i = 0; i < npts; i++) {
|
||||
eval_4_isog(pts[i], coeff);
|
||||
}
|
||||
fp2copy(pts[npts - 1]->X, R->X);
|
||||
fp2copy(pts[npts - 1]->Z, R->Z);
|
||||
index = pts_index[npts - 1];
|
||||
npts -= 1;
|
||||
}
|
||||
|
||||
fp2copy(pts[npts-1]->X, R->X);
|
||||
fp2copy(pts[npts-1]->Z, R->Z);
|
||||
index = pts_index[npts-1];
|
||||
npts -= 1;
|
||||
}
|
||||
get_4_isog(R, A24plus, C24, coeff);
|
||||
fp2div2(C24, C24);
|
||||
fp2sub(A24plus, C24, A24plus);
|
||||
fp2div2(C24, C24);
|
||||
j_inv(A24plus, C24, jinv);
|
||||
fp2_encode(jinv, SharedSecretA); // Format shared secret
|
||||
|
||||
get_4_isog(R, A24plus, C24, coeff);
|
||||
fp2div2(C24, C24);
|
||||
fp2sub(A24plus, C24, A24plus);
|
||||
fp2div2(C24, C24);
|
||||
j_inv(A24plus, C24, jinv);
|
||||
fp2_encode(jinv, SharedSecretA); // Format shared secret
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EphemeralSecretAgreement_B(const unsigned char *PrivateKeyB, const unsigned char *PublicKeyA, unsigned char *SharedSecretB) { // Bob's ephemeral shared secret computation
|
||||
// It produces a shared secret key SharedSecretB using his secret key PrivateKeyB and Alice's public key PublicKeyA
|
||||
// Inputs: Bob's PrivateKeyB is an integer in the range [0, 2^Floor(Log(2,oB)) - 1].
|
||||
// Alice's PublicKeyA consists of 3 elements in GF(p^2) encoded by removing leading 0 bytes.
|
||||
// Output: a shared secret SharedSecretB that consists of one element in GF(p^2) encoded by removing leading 0 bytes.
|
||||
point_proj_t R, pts[MAX_INT_POINTS_BOB];
|
||||
f2elm_t coeff[3], PKB[3], jinv;
|
||||
f2elm_t A24plus = {0}, A24minus = {0}, A = {0};
|
||||
unsigned int i, row, m, index = 0, pts_index[MAX_INT_POINTS_BOB], npts = 0, ii = 0;
|
||||
|
||||
int EphemeralSecretAgreement_B(const unsigned char* PrivateKeyB, const unsigned char* PublicKeyA, unsigned char* SharedSecretB)
|
||||
{ // Bob's ephemeral shared secret computation
|
||||
// It produces a shared secret key SharedSecretB using his secret key PrivateKeyB and Alice's public key PublicKeyA
|
||||
// Inputs: Bob's PrivateKeyB is an integer in the range [0, 2^Floor(Log(2,oB)) - 1].
|
||||
// Alice's PublicKeyA consists of 3 elements in GF(p^2) encoded by removing leading 0 bytes.
|
||||
// Output: a shared secret SharedSecretB that consists of one element in GF(p^2) encoded by removing leading 0 bytes.
|
||||
point_proj_t R, pts[MAX_INT_POINTS_BOB];
|
||||
f2elm_t coeff[3], PKB[3], jinv;
|
||||
f2elm_t A24plus = {0}, A24minus = {0}, A = {0};
|
||||
unsigned int i, row, m, index = 0, pts_index[MAX_INT_POINTS_BOB], npts = 0, ii = 0;
|
||||
// Initialize images of Alice's basis
|
||||
fp2_decode(PublicKeyA, PKB[0]);
|
||||
fp2_decode(PublicKeyA + FP2_ENCODED_BYTES, PKB[1]);
|
||||
fp2_decode(PublicKeyA + 2 * FP2_ENCODED_BYTES, PKB[2]);
|
||||
|
||||
// Initialize images of Alice's basis
|
||||
fp2_decode(PublicKeyA, PKB[0]);
|
||||
fp2_decode(PublicKeyA + FP2_ENCODED_BYTES, PKB[1]);
|
||||
fp2_decode(PublicKeyA + 2*FP2_ENCODED_BYTES, PKB[2]);
|
||||
// Initialize constants
|
||||
get_A(PKB[0], PKB[1], PKB[2], A); // TODO: Can return projective A?
|
||||
fpadd((digit_t *) &Montgomery_one, (digit_t *) &Montgomery_one, A24minus[0]);
|
||||
fp2add(A, A24minus, A24plus);
|
||||
fp2sub(A, A24minus, A24minus);
|
||||
|
||||
// Initialize constants
|
||||
get_A(PKB[0], PKB[1], PKB[2], A); // TODO: Can return projective A?
|
||||
fpadd((digit_t*)&Montgomery_one, (digit_t*)&Montgomery_one, A24minus[0]);
|
||||
fp2add(A, A24minus, A24plus);
|
||||
fp2sub(A, A24minus, A24minus);
|
||||
// Retrieve kernel point
|
||||
LADDER3PT(PKB[0], PKB[1], PKB[2], (digit_t *) PrivateKeyB, BOB, R, A);
|
||||
|
||||
// Retrieve kernel point
|
||||
LADDER3PT(PKB[0], PKB[1], PKB[2], (digit_t*)PrivateKeyB, BOB, R, A);
|
||||
// Traverse tree
|
||||
index = 0;
|
||||
for (row = 1; row < MAX_Bob; row++) {
|
||||
while (index < MAX_Bob - row) {
|
||||
fp2copy(R->X, pts[npts]->X);
|
||||
fp2copy(R->Z, pts[npts]->Z);
|
||||
pts_index[npts++] = index;
|
||||
m = strat_Bob[ii++];
|
||||
xTPLe(R, R, A24minus, A24plus, (int) m);
|
||||
index += m;
|
||||
}
|
||||
get_3_isog(R, A24minus, A24plus, coeff);
|
||||
|
||||
// Traverse tree
|
||||
index = 0;
|
||||
for (row = 1; row < MAX_Bob; row++) {
|
||||
while (index < MAX_Bob-row) {
|
||||
fp2copy(R->X, pts[npts]->X);
|
||||
fp2copy(R->Z, pts[npts]->Z);
|
||||
pts_index[npts++] = index;
|
||||
m = strat_Bob[ii++];
|
||||
xTPLe(R, R, A24minus, A24plus, (int)m);
|
||||
index += m;
|
||||
}
|
||||
get_3_isog(R, A24minus, A24plus, coeff);
|
||||
for (i = 0; i < npts; i++) {
|
||||
eval_3_isog(pts[i], coeff);
|
||||
}
|
||||
|
||||
for (i = 0; i < npts; i++) {
|
||||
eval_3_isog(pts[i], coeff);
|
||||
}
|
||||
fp2copy(pts[npts - 1]->X, R->X);
|
||||
fp2copy(pts[npts - 1]->Z, R->Z);
|
||||
index = pts_index[npts - 1];
|
||||
npts -= 1;
|
||||
}
|
||||
|
||||
fp2copy(pts[npts-1]->X, R->X);
|
||||
fp2copy(pts[npts-1]->Z, R->Z);
|
||||
index = pts_index[npts-1];
|
||||
npts -= 1;
|
||||
}
|
||||
get_3_isog(R, A24minus, A24plus, coeff);
|
||||
fp2add(A24plus, A24minus, A);
|
||||
fp2add(A, A, A);
|
||||
fp2sub(A24plus, A24minus, A24plus);
|
||||
j_inv(A, A24plus, jinv);
|
||||
fp2_encode(jinv, SharedSecretB); // Format shared secret
|
||||
|
||||
get_3_isog(R, A24minus, A24plus, coeff);
|
||||
fp2add(A24plus, A24minus, A);
|
||||
fp2add(A, A, A);
|
||||
fp2sub(A24plus, A24minus, A24plus);
|
||||
j_inv(A, A24plus, jinv);
|
||||
fp2_encode(jinv, SharedSecretB); // Format shared secret
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -7,92 +7,88 @@
|
||||
#include <string.h>
|
||||
#include "sha3/fips202.h"
|
||||
|
||||
int crypto_kem_keypair(unsigned char *pk, unsigned char *sk, OQS_RAND *rand) { // SIKE's key generation
|
||||
// Outputs: secret key sk (CRYPTO_SECRETKEYBYTES = MSG_BYTES + SECRETKEY_B_BYTES + CRYPTO_PUBLICKEYBYTES bytes)
|
||||
// public key pk (CRYPTO_PUBLICKEYBYTES bytes)
|
||||
|
||||
int crypto_kem_keypair(unsigned char *pk, unsigned char *sk, OQS_RAND *rand)
|
||||
{ // SIKE's key generation
|
||||
// Outputs: secret key sk (CRYPTO_SECRETKEYBYTES = MSG_BYTES + SECRETKEY_B_BYTES + CRYPTO_PUBLICKEYBYTES bytes)
|
||||
// public key pk (CRYPTO_PUBLICKEYBYTES bytes)
|
||||
// Generate lower portion of secret key sk <- s||SK
|
||||
OQS_RAND_n(rand, sk, MSG_BYTES);
|
||||
random_mod_order_B(sk + MSG_BYTES, rand);
|
||||
|
||||
// Generate lower portion of secret key sk <- s||SK
|
||||
OQS_RAND_n(rand, sk, MSG_BYTES);
|
||||
random_mod_order_B(sk + MSG_BYTES, rand);
|
||||
// Generate public key pk
|
||||
EphemeralKeyGeneration_B(sk + MSG_BYTES, pk, rand);
|
||||
|
||||
// Generate public key pk
|
||||
EphemeralKeyGeneration_B(sk + MSG_BYTES, pk, rand);
|
||||
// Append public key pk to secret key sk
|
||||
memcpy(&sk[MSG_BYTES + SECRETKEY_B_BYTES], pk, CRYPTO_PUBLICKEYBYTES);
|
||||
|
||||
// Append public key pk to secret key sk
|
||||
memcpy(&sk[MSG_BYTES + SECRETKEY_B_BYTES], pk, CRYPTO_PUBLICKEYBYTES);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypto_kem_enc(unsigned char *ct, unsigned char *ss, const unsigned char *pk, OQS_RAND *rand) { // SIKE's encapsulation
|
||||
// Input: public key pk (CRYPTO_PUBLICKEYBYTES bytes)
|
||||
// Outputs: shared secret ss (CRYPTO_BYTES bytes)
|
||||
// ciphertext message ct (CRYPTO_CIPHERTEXTBYTES = CRYPTO_PUBLICKEYBYTES + MSG_BYTES bytes)
|
||||
const uint16_t G = 0;
|
||||
const uint16_t H = 1;
|
||||
const uint16_t P = 2;
|
||||
unsigned char ephemeralsk[SECRETKEY_A_BYTES];
|
||||
unsigned char jinvariant[FP2_ENCODED_BYTES];
|
||||
unsigned char h[MSG_BYTES];
|
||||
unsigned char temp[CRYPTO_CIPHERTEXTBYTES + MSG_BYTES];
|
||||
unsigned int i;
|
||||
|
||||
int crypto_kem_enc(unsigned char *ct, unsigned char *ss, const unsigned char *pk, OQS_RAND *rand)
|
||||
{ // SIKE's encapsulation
|
||||
// Input: public key pk (CRYPTO_PUBLICKEYBYTES bytes)
|
||||
// Outputs: shared secret ss (CRYPTO_BYTES bytes)
|
||||
// ciphertext message ct (CRYPTO_CIPHERTEXTBYTES = CRYPTO_PUBLICKEYBYTES + MSG_BYTES bytes)
|
||||
const uint16_t G = 0;
|
||||
const uint16_t H = 1;
|
||||
const uint16_t P = 2;
|
||||
unsigned char ephemeralsk[SECRETKEY_A_BYTES];
|
||||
unsigned char jinvariant[FP2_ENCODED_BYTES];
|
||||
unsigned char h[MSG_BYTES];
|
||||
unsigned char temp[CRYPTO_CIPHERTEXTBYTES+MSG_BYTES];
|
||||
unsigned int i;
|
||||
// Generate ephemeralsk <- G(m||pk) mod oA
|
||||
OQS_RAND_n(rand, temp, MSG_BYTES);
|
||||
memcpy(&temp[MSG_BYTES], pk, CRYPTO_PUBLICKEYBYTES);
|
||||
cshake256_simple(ephemeralsk, SECRETKEY_A_BYTES, G, temp, CRYPTO_PUBLICKEYBYTES + MSG_BYTES);
|
||||
ephemeralsk[SECRETKEY_A_BYTES - 1] &= MASK_ALICE;
|
||||
|
||||
// Generate ephemeralsk <- G(m||pk) mod oA
|
||||
OQS_RAND_n(rand, temp, MSG_BYTES);
|
||||
memcpy(&temp[MSG_BYTES], pk, CRYPTO_PUBLICKEYBYTES);
|
||||
cshake256_simple(ephemeralsk, SECRETKEY_A_BYTES, G, temp, CRYPTO_PUBLICKEYBYTES+MSG_BYTES);
|
||||
ephemeralsk[SECRETKEY_A_BYTES - 1] &= MASK_ALICE;
|
||||
// Encrypt
|
||||
EphemeralKeyGeneration_A(ephemeralsk, ct, rand);
|
||||
EphemeralSecretAgreement_A(ephemeralsk, pk, jinvariant);
|
||||
cshake256_simple(h, MSG_BYTES, P, jinvariant, FP2_ENCODED_BYTES);
|
||||
for (i = 0; i < MSG_BYTES; i++)
|
||||
ct[i + CRYPTO_PUBLICKEYBYTES] = temp[i] ^ h[i];
|
||||
|
||||
// Encrypt
|
||||
EphemeralKeyGeneration_A(ephemeralsk, ct, rand);
|
||||
EphemeralSecretAgreement_A(ephemeralsk, pk, jinvariant);
|
||||
cshake256_simple(h, MSG_BYTES, P, jinvariant, FP2_ENCODED_BYTES);
|
||||
for (i = 0; i < MSG_BYTES; i++) ct[i + CRYPTO_PUBLICKEYBYTES] = temp[i] ^ h[i];
|
||||
// Generate shared secret ss <- H(m||ct)
|
||||
memcpy(&temp[MSG_BYTES], ct, CRYPTO_CIPHERTEXTBYTES);
|
||||
cshake256_simple(ss, CRYPTO_BYTES, H, temp, CRYPTO_CIPHERTEXTBYTES + MSG_BYTES);
|
||||
|
||||
// Generate shared secret ss <- H(m||ct)
|
||||
memcpy(&temp[MSG_BYTES], ct, CRYPTO_CIPHERTEXTBYTES);
|
||||
cshake256_simple(ss, CRYPTO_BYTES, H, temp, CRYPTO_CIPHERTEXTBYTES+MSG_BYTES);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypto_kem_dec(unsigned char *ss, const unsigned char *ct, const unsigned char *sk, OQS_RAND *rand) { // SIKE's decapsulation
|
||||
// Input: secret key sk (CRYPTO_SECRETKEYBYTES = MSG_BYTES + SECRETKEY_B_BYTES + CRYPTO_PUBLICKEYBYTES bytes)
|
||||
// ciphertext message ct (CRYPTO_CIPHERTEXTBYTES = CRYPTO_PUBLICKEYBYTES + MSG_BYTES bytes)
|
||||
// Outputs: shared secret ss (CRYPTO_BYTES bytes)
|
||||
const uint16_t G = 0;
|
||||
const uint16_t H = 1;
|
||||
const uint16_t P = 2;
|
||||
unsigned char ephemeralsk_[SECRETKEY_A_BYTES];
|
||||
unsigned char jinvariant_[FP2_ENCODED_BYTES];
|
||||
unsigned char h_[MSG_BYTES];
|
||||
unsigned char c0_[CRYPTO_PUBLICKEYBYTES];
|
||||
unsigned char temp[CRYPTO_CIPHERTEXTBYTES + MSG_BYTES];
|
||||
unsigned int i;
|
||||
|
||||
int crypto_kem_dec(unsigned char *ss, const unsigned char *ct, const unsigned char *sk, OQS_RAND *rand)
|
||||
{ // SIKE's decapsulation
|
||||
// Input: secret key sk (CRYPTO_SECRETKEYBYTES = MSG_BYTES + SECRETKEY_B_BYTES + CRYPTO_PUBLICKEYBYTES bytes)
|
||||
// ciphertext message ct (CRYPTO_CIPHERTEXTBYTES = CRYPTO_PUBLICKEYBYTES + MSG_BYTES bytes)
|
||||
// Outputs: shared secret ss (CRYPTO_BYTES bytes)
|
||||
const uint16_t G = 0;
|
||||
const uint16_t H = 1;
|
||||
const uint16_t P = 2;
|
||||
unsigned char ephemeralsk_[SECRETKEY_A_BYTES];
|
||||
unsigned char jinvariant_[FP2_ENCODED_BYTES];
|
||||
unsigned char h_[MSG_BYTES];
|
||||
unsigned char c0_[CRYPTO_PUBLICKEYBYTES];
|
||||
unsigned char temp[CRYPTO_CIPHERTEXTBYTES+MSG_BYTES];
|
||||
unsigned int i;
|
||||
// Decrypt
|
||||
EphemeralSecretAgreement_B(sk + MSG_BYTES, ct, jinvariant_);
|
||||
cshake256_simple(h_, MSG_BYTES, P, jinvariant_, FP2_ENCODED_BYTES);
|
||||
for (i = 0; i < MSG_BYTES; i++)
|
||||
temp[i] = ct[i + CRYPTO_PUBLICKEYBYTES] ^ h_[i];
|
||||
|
||||
// Decrypt
|
||||
EphemeralSecretAgreement_B(sk + MSG_BYTES, ct, jinvariant_);
|
||||
cshake256_simple(h_, MSG_BYTES, P, jinvariant_, FP2_ENCODED_BYTES);
|
||||
for (i = 0; i < MSG_BYTES; i++) temp[i] = ct[i + CRYPTO_PUBLICKEYBYTES] ^ h_[i];
|
||||
// Generate ephemeralsk_ <- G(m||pk) mod oA
|
||||
memcpy(&temp[MSG_BYTES], &sk[MSG_BYTES + SECRETKEY_B_BYTES], CRYPTO_PUBLICKEYBYTES);
|
||||
cshake256_simple(ephemeralsk_, SECRETKEY_A_BYTES, G, temp, CRYPTO_PUBLICKEYBYTES + MSG_BYTES);
|
||||
ephemeralsk_[SECRETKEY_A_BYTES - 1] &= MASK_ALICE;
|
||||
|
||||
// Generate ephemeralsk_ <- G(m||pk) mod oA
|
||||
memcpy(&temp[MSG_BYTES], &sk[MSG_BYTES + SECRETKEY_B_BYTES], CRYPTO_PUBLICKEYBYTES);
|
||||
cshake256_simple(ephemeralsk_, SECRETKEY_A_BYTES, G, temp, CRYPTO_PUBLICKEYBYTES+MSG_BYTES);
|
||||
ephemeralsk_[SECRETKEY_A_BYTES - 1] &= MASK_ALICE;
|
||||
// Generate shared secret ss <- H(m||ct) or output ss <- H(s||ct)
|
||||
EphemeralKeyGeneration_A(ephemeralsk_, c0_, rand);
|
||||
if (memcmp(c0_, ct, CRYPTO_PUBLICKEYBYTES) != 0) {
|
||||
memcpy(temp, sk, MSG_BYTES);
|
||||
}
|
||||
memcpy(&temp[MSG_BYTES], ct, CRYPTO_CIPHERTEXTBYTES);
|
||||
cshake256_simple(ss, CRYPTO_BYTES, H, temp, CRYPTO_CIPHERTEXTBYTES + MSG_BYTES);
|
||||
|
||||
// Generate shared secret ss <- H(m||ct) or output ss <- H(s||ct)
|
||||
EphemeralKeyGeneration_A(ephemeralsk_, c0_, rand);
|
||||
if (memcmp(c0_, ct, CRYPTO_PUBLICKEYBYTES) != 0) {
|
||||
memcpy(temp, sk, MSG_BYTES);
|
||||
}
|
||||
memcpy(&temp[MSG_BYTES], ct, CRYPTO_CIPHERTEXTBYTES);
|
||||
cshake256_simple(ss, CRYPTO_BYTES, H, temp, CRYPTO_CIPHERTEXTBYTES+MSG_BYTES);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user