|
- #include <stdint.h>
- #include <stdio.h>
- #include <string.h>
-
- #include "./sidh_ref/P751_internal.h"
-
- #include "measurements.h"
-
- #ifndef PRIME_BITS
- #define PRIME_BITS 751
- #endif
-
- #define DIGITS_64 ((PRIME_BITS + 63) / 64)
- #define DIGITS_52 ((PRIME_BITS + 51) / 52)
-
- #define OALICE_BITS 372
- #define OBOB_BITS 379
- #define SECRETKEY_A_BYTES (OALICE_BITS + 7) / 8
- #define SECRETKEY_B_BYTES (OBOB_BITS + 7) / 8
-
- #define MASK_ALICE 0x0F
- #define MASK_BOB 0x03
-
- typedef uint64_t num52[DIGITS_52];
- typedef num52 felem[2];
-
- void fp2_mul_ifma(felem res, felem a, felem b);
- void fp2_sqr_ifma(felem res, felem a);
- void fp2_mul_ifma_x2(felem res1, const felem a1, const felem b1, felem res2, const felem a2, const felem b2);
- void fp_mul_ifma(uint64_t *rp, const uint64_t *ap, const uint64_t *bp);
- void to_mont_ifma(uint64_t *rp, const uint64_t *ap);
- void from_mont_ifma(uint64_t *rp, const uint64_t *ap);
-
- void red2norm(uint64_t out[12], const uint64_t in[15]);
- void norm2red(uint64_t *res, const uint64_t *a);
-
- int EphemeralKeyGeneration_A_ifma(const unsigned char *PrivateKeyA, unsigned char *PublicKeyA);
- int EphemeralKeyGeneration_B_ifma(const unsigned char *PrivateKeyB, unsigned char *PublicKeyB);
-
- int rdrand64_step(uint64_t *rand)
- {
- unsigned char ok;
- __asm__ volatile("rdrand %0; setc %1"
- : "=r"(*rand), "=qm"(ok));
- return (int)ok;
- }
-
- static void rand_750(uint64_t out[DIGITS_64])
- {
- for (int i = 0; i < DIGITS_64; i++)
- {
- while (!rdrand64_step((uint64_t *)&out[i]))
- ;
- }
-
- out[DIGITS_64 - 1] &= ((1ULL << (PRIME_BITS - 64 * (DIGITS_64 - 1))) - 1);
- }
-
- static void rand_bytes(uint8_t *out, size_t out_len)
- {
- uint64_t temp;
- for (int i = 0; i < out_len; i++)
- {
- while (!rdrand64_step((uint64_t *)&temp))
- ;
- out[i] = temp;
- }
- }
-
- int main()
- {
-
- int i;
-
- do
- {
- felm_t fa, fb, fr;
- num52 r, a, b;
- uint64_t res_ifma[DIGITS_64];
-
- rand_750(fa);
- rand_750(fb);
-
- norm2red(a, (uint64_t *)fa);
- norm2red(b, (uint64_t *)fb);
- to_mont_ifma(a, a);
- to_mont_ifma(b, b);
-
- MEASURE({ fp_mul_ifma(r, a, b); });
-
- from_mont_ifma(r, r);
- red2norm(res_ifma, r);
- printf("Mont mul IFMA Cycles/op: %.0f\n", RDTSC_total_clk);
-
- to_mont(fa, fa);
- to_mont(fb, fb);
- MEASURE({ fpmul751_mont(fa, fb, fr); });
- from_mont(fr, fr);
- printf("Mont mul ref Cycles/op: %.0f\n", RDTSC_total_clk);
-
- printf("%s\n", memcmp(fr, res_ifma, sizeof(res_ifma)) ? "FP MUL Fail"
- : "FP MUL Success");
- } while (0);
-
- do
- {
- felem a, b, r, r2;
- f2elm_t fa, fb, fr;
- uint64_t res_ifma[2][DIGITS_64];
-
- rand_750(fa[0]);
- rand_750(fa[1]);
- rand_750(fb[0]);
- rand_750(fb[1]);
- norm2red(a[0], (uint64_t *)fa[0]);
- norm2red(a[1], (uint64_t *)fa[1]);
- norm2red(b[0], (uint64_t *)fb[0]);
- norm2red(b[1], (uint64_t *)fb[1]);
- to_mont_ifma(a[0], a[0]);
- to_mont_ifma(a[1], a[1]);
- to_mont_ifma(b[0], b[0]);
- to_mont_ifma(b[1], b[1]);
-
- MEASURE({ fp2_mul_ifma(r, a, b); });
-
- from_mont_ifma(r[0], r[0]);
- from_mont_ifma(r[1], r[1]);
- red2norm(res_ifma[0], r[0]);
- red2norm(res_ifma[1], r[1]);
- printf("Mont FP2 mul IFMA Cycles/op: %.0f\n", RDTSC_total_clk);
-
- to_mont(fa[0], fa[0]);
- to_mont(fa[1], fa[1]);
- to_mont(fb[0], fb[0]);
- to_mont(fb[1], fb[1]);
-
- MEASURE({ fp2mul751_mont(fa, fb, fr); });
-
- from_mont(fr[0], fr[0]);
- from_mont(fr[1], fr[1]);
- printf("Mont FP2 mul ref Cycles/op: %.0f\n", RDTSC_total_clk);
-
- printf("%s\n", memcmp(fr, res_ifma, sizeof(res_ifma)) ? "FP2 MUL Fail"
- : "FP2 MUL Success");
-
- MEASURE({ fp2_mul_ifma_x2(r, a, b, r2, a, b); });
-
- from_mont_ifma(r[0], r[0]);
- from_mont_ifma(r[1], r[1]);
- red2norm(res_ifma[0], r[0]);
- red2norm(res_ifma[1], r[1]);
-
- printf("Dual Mont FP2 mul IFMA Cycles/op: %.0f\n", RDTSC_total_clk);
-
- printf("%s\n", memcmp(fr, res_ifma, sizeof(res_ifma)) ? "Dual FP2 MUL 1/2 Fail"
- : "Dual FP2 MUL 1/2 Success");
-
- from_mont_ifma(r2[0], r2[0]);
- from_mont_ifma(r2[1], r2[1]);
- red2norm(res_ifma[0], r2[0]);
- red2norm(res_ifma[1], r2[1]);
-
- printf("%s\n", memcmp(fr, res_ifma, sizeof(res_ifma)) ? "Dual FP2 MUL 2/2 Fail"
- : "Dual FP2 MUL 2/2 Success");
-
- MEASURE({ fp2_sqr_ifma(r, a); });
-
- from_mont_ifma(r[0], r[0]);
- from_mont_ifma(r[1], r[1]);
- red2norm(res_ifma[0], r[0]);
- red2norm(res_ifma[1], r[1]);
- printf("Mont FP2 sqr IFMA Cycles/op: %.0f\n", RDTSC_total_clk);
-
- MEASURE({ fp2sqr751_mont(fa, fr); });
-
- from_mont(fr[0], fr[0]);
- from_mont(fr[1], fr[1]);
- printf("Mont FP2 sqr ref Cycles/op: %.0f\n", RDTSC_total_clk);
-
- printf("%s\n", memcmp(fr, res_ifma, sizeof(res_ifma)) ? "FP2 SQR Fail"
- : "FP2 SQR Success");
-
- } while (0);
-
- do
- {
- unsigned char ephemeralsk_alice[SECRETKEY_A_BYTES];
- unsigned char ephemeralsk_bob[SECRETKEY_B_BYTES];
- unsigned char ct1[564] = {0};
- unsigned char ct2[564] = {0};
- rand_bytes(ephemeralsk_alice, sizeof(ephemeralsk_alice));
- rand_bytes(ephemeralsk_bob, sizeof(ephemeralsk_bob));
- ephemeralsk_alice[SECRETKEY_A_BYTES - 1] &= MASK_ALICE;
- ephemeralsk_bob[SECRETKEY_B_BYTES - 1] &= MASK_BOB;
-
- MEASURE({ EphemeralKeyGeneration_A(ephemeralsk_alice, ct1); });
-
- printf("Ref EphemeralKeyGeneration_A Cycles/op: %.0f\n", RDTSC_total_clk);
-
- MEASURE({ EphemeralKeyGeneration_A_ifma(ephemeralsk_alice, ct2); });
-
- printf("IFMA EphemeralKeyGeneration_A Cycles/op: %.0f\n", RDTSC_total_clk);
-
- printf("%s\n", memcmp(ct1, ct2, sizeof(ct1)) ? "EphemeralKeyGeneration_A Fail"
- : "EphemeralKeyGeneration_A Success");
-
- MEASURE({ EphemeralKeyGeneration_B(ephemeralsk_bob, ct1); });
-
- printf("Ref EphemeralKeyGeneration_B Cycles/op: %.0f\n", RDTSC_total_clk);
-
- MEASURE({ EphemeralKeyGeneration_B_ifma(ephemeralsk_bob, ct2); });
-
- printf("IFMA EphemeralKeyGeneration_B Cycles/op: %.0f\n", RDTSC_total_clk);
-
- printf("%s\n", memcmp(ct1, ct2, sizeof(ct1)) ? "EphemeralKeyGeneration_B Fail"
- : "EphemeralKeyGeneration_B Success");
- } while (0);
- }
|