Selaa lähdekoodia

Files for rms multiplications.

Michele Orrù 7 vuotta sitten
vanhempi
commit
05e234191c
12 muutettua tiedostoa jossa 475 lisäystä ja 0 poistoa
  1. 2 0
      Makefile.am
  2. 44 0
      configure.ac
  3. 9 0
      src/Makefile.am
  4. 50 0
      src/elgamal.c
  5. 20 0
      src/elgamal.h
  6. 12 0
      src/entropy.c
  7. 18 0
      src/entropy.h
  8. 60 0
      src/hss.c
  9. 42 0
      src/hss.h
  10. 188 0
      src/rms.c
  11. 12 0
      src/rms.h
  12. 18 0
      src/timeit.h

+ 2 - 0
Makefile.am

@@ -0,0 +1,2 @@
+SUBDIRS = src/
+AUTOMAKE_ARGS = --add-missing

+ 44 - 0
configure.ac

@@ -0,0 +1,44 @@
+#                                               -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ([2.65])
+AC_INIT([ccs], [0.1], [michele.orru@ens.fr])
+AM_INIT_AUTOMAKE
+AC_CONFIG_SRCDIR([src/rms.c])
+AC_CONFIG_HEADERS([src/config.h])
+
+# Checks for programs.
+AC_PROG_CC([gcc clang cc])
+AC_PROG_CC_C99
+AC_PROG_RANLIB
+
+# Checks for libraries.
+
+# have _GNU_SOURCE defined aroud.
+AC_GNU_SOURCE
+
+# Checks for header files.
+AC_CHECK_HEADERS([limits.h stdint.h stdlib.h string.h unistd.h])
+AC_CHECK_LIB(gmp, __gmpz_init, ,
+[AC_MSG_ERROR([GNU MP not found, see https://gmplib.org/])])
+AC_CHECK_SIZEOF(mp_limb_t, 8, [#include <gmp.h>])
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_TYPE_SIZE_T
+
+# Checks for library functions.
+AC_FUNC_ERROR_AT_LINE
+AC_FUNC_MALLOC
+#AC_CHECK_FUNCS([dup2 setlocale strdup])
+
+# Add compiler/linker flags
+CFLAGS="--std=c99 -Wall -march=native"
+
+# Adding package options
+AC_ARG_ENABLE(debug,
+   AS_HELP_STRING([--enable-debug], [enable debugging, default: no]),
+   CFLAGS+=" -DDEBUG -DBN_DEBUG -O0 -ggdb")
+
+AC_OUTPUT([Makefile
+           src/Makefile
+           ])

+ 9 - 0
src/Makefile.am

@@ -0,0 +1,9 @@
+bin_PROGRAMS = rms
+
+
+HSS = hss.c hss.h
+ENTROPY = entropy.c entropy.h
+ELGAMAL = elgamal.c elgamal.h
+
+rms_SOURCES = rms.c $(HSS) $(ENTROPY) $(ELGAMAL)
+rms_LDADD = -lgmp

+ 50 - 0
src/elgamal.c

@@ -0,0 +1,50 @@
+#include "config.h"
+
+#include <gmp.h>
+
+#include "elgamal.h"
+#include "entropy.h"
+#include "hss.h"
+
+
+elgamal_key_t elgamal_keygen()
+{
+  elgamal_key_t rop;
+  mpz_init(rop.sk);
+  mpz_init_set_ui(rop.pk, 2);
+
+  mpz_urandomm(rop.sk, _rstate, q);
+  mpz_powm(rop.pk, rop.pk, rop.sk, p);
+  return rop;
+}
+
+elgamal_cipher_t elgamal_encrypt(elgamal_key_t k, mpz_t m)
+{
+  mpz_t x;
+  elgamal_cipher_t rop;
+
+  mpz_init(x);
+  mpz_urandomm(x, _rstate, q);
+
+  mpz_init_set_ui(rop.c1, 2);
+  mpz_powm(rop.c1, rop.c1, x, p);
+
+  mpz_init_set(rop.c2, k.pk);
+  mpz_powm(rop.c2, rop.c2, x, p);
+  mpz_set_ui(x, 2);
+  mpz_powm(x, x, m, p);
+  mpz_mul(rop.c2, rop.c2, x);
+  mpz_mod(rop.c2, rop.c2, p);
+
+  mpz_clear(x);
+  return rop;
+}
+
+
+void elgamal_decrypt(mpz_t rop, elgamal_key_t k, elgamal_cipher_t c)
+{
+  mpz_powm(rop, c.c1, k.sk, p);
+  mpz_invert(rop, rop, p);
+  mpz_mul(rop, rop, c.c2);
+  mpz_mod(rop, rop, p);
+}

+ 20 - 0
src/elgamal.h

@@ -0,0 +1,20 @@
+#pragma once
+#include "config.h"
+
+#include <gmp.h>
+
+#include "entropy.h"
+
+typedef struct elgamal_key {
+  mpz_t sk;
+  mpz_t pk;
+} elgamal_key_t;
+
+typedef struct elgamal_cipher {
+  mpz_t c1;
+  mpz_t c2;
+} elgamal_cipher_t;
+
+elgamal_key_t elgamal_keygen();
+elgamal_cipher_t elgamal_encrypt(elgamal_key_t k, mpz_t m);
+void elgamal_decrypt(mpz_t rop, elgamal_key_t k, elgamal_cipher_t c);

+ 12 - 0
src/entropy.c

@@ -0,0 +1,12 @@
+#include "config.h"
+#include "entropy.h"
+
+gmp_randstate_t _rstate;
+unsigned long int _rseed;
+
+void mpz_entropy_init()
+{
+  gmp_randinit_default(_rstate);
+  getrandom(&_rseed, sizeof(unsigned long int), GRND_NONBLOCK);
+  gmp_randseed_ui(_rstate, _rseed);
+}

+ 18 - 0
src/entropy.h

@@ -0,0 +1,18 @@
+#pragma once
+#include <linux/random.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+#include <gmp.h>
+
+extern gmp_randstate_t _rstate;
+extern unsigned long int _rseed;
+
+static inline ssize_t
+getrandom(void *buffer, size_t length, unsigned int flags)
+{
+  return syscall(SYS_getrandom, buffer, length, flags);
+}
+
+
+void mpz_entropy_init();

+ 60 - 0
src/hss.c

@@ -0,0 +1,60 @@
+#include "hss.h"
+
+/**
+ * p is our prime modulus, and is 2^n - g
+ * where g is referred to as "gamma" (built-in function in C, so transliterated)
+ */
+const char* p_str =
+  "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+  "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+  "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+  "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+  "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+  "505CAF";
+
+mpz_t p, q;
+uint32_t gg = 11510609;
+
+void hss_init()
+{
+  mpz_init_set_str(p, p_str, 0);
+
+  mpz_init_set(q, p);
+  mpz_sub_ui(q, q, 1);
+  mpz_divexact_ui(q, q, 2);
+}
+
+
+void hss_del()
+{
+  mpz_clear(p);
+}
+
+void ssl1_init(ssl1_t s)
+{
+  /* mpz_init(s->w); */
+  /* for (size_t t = 0; t < 160; t++) { */
+  /*   mpz_init(s->cw[t]); */
+  /* } */
+}
+
+void ssl1_clear(ssl1_t s)
+{
+  mpz_clears(s->w.c1, s->w.c2, NULL);
+
+  for (size_t t = 0; t < 160; t++) {
+    mpz_clears(s->cw[t].c1, s->cw[t].c2, NULL);
+  }
+}
+
+void ssl2_init(ssl2_t s)
+{
+  mpz_init(s->x);
+  mpz_init(s->cx);
+}
+
+void ssl2_clear(ssl2_t s)
+{
+  mpz_clear(s->x);
+  mpz_clear(s->cx);
+}

+ 42 - 0
src/hss.h

@@ -0,0 +1,42 @@
+#pragma once
+
+#include <gmp.h>
+#include <stdint.h>
+
+#include "elgamal.h"
+
+/**
+ * p is our prime modulus, and is 2^n - g
+ * where g is referred to as "gamma" (built-in function in C, so transliterated)
+ */
+extern const char* p_str;
+extern mpz_t p, q;
+extern uint32_t gg;
+
+void hss_init();
+void hss_del();
+
+
+/** A level-1 share is the El-Gamal encryption of a secretly-shared value,
+ *  plus the encryption of the product of each bit.
+ */
+typedef struct ssl1 {
+  elgamal_cipher_t w;
+  elgamal_cipher_t cw[160];
+} ssl1_t[1];
+
+
+void ssl1_init(ssl1_t s);
+void ssl1_clear(ssl1_t s);
+
+/** A level-2 share are subractive shares.
+    This shares have at most 192 bits.
+ */
+typedef struct ssl2 {
+  mpz_t x;
+  mpz_t cx;
+} ssl2_t[1];
+
+#define ssl2_add(rop, a, b) mpz_add(rop, a, b)
+void ssl2_init(ssl2_t s);
+void ssl2_clear(ssl2_t s);

+ 188 - 0
src/rms.c

@@ -0,0 +1,188 @@
+#include "config.h"
+
+#include <assert.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+#include <gmp.h>
+
+#include "elgamal.h"
+#include "entropy.h"
+#include "rms.h"
+#include "hss.h"
+#include "timeit.h"
+
+/** this function is only for testing purposes. */
+void ssl2_share(ssl2_t s1, ssl2_t s2, const mpz_t v, const mpz_t sk)
+{
+  mpz_rrandomb(s1->x, _rstate, 192);
+  mpz_add(s2->x, v, s1->x);
+
+  mpz_rrandomb(s1->cx, _rstate, 192);
+  mpz_mul(s2->cx, sk, v);
+  mpz_add(s2->cx, s2->cx, s1->cx);
+}
+
+
+void ssl2_merge(mpz_t rop, const ssl2_t s1, const ssl2_t s2)
+{
+
+  mpz_sub(rop, s2->x, s1->x);
+}
+
+
+void ssl1_share(ssl1_t r1, ssl1_t r2, const mpz_t v, const elgamal_key_t key)
+{
+  mpz_t x, zero;
+  mpz_init(x);
+  mpz_init_set_ui(zero, 0);
+  /* first share is random */
+  mpz_urandomm(x, _rstate, q);
+
+  r1->w = elgamal_encrypt(key, x);
+  for (size_t t = 0; t < 160; t++) {
+    if (mpz_tstbit(key.sk, t)) {
+      r1->cw[t] = elgamal_encrypt(key, x);
+    } else {
+      r1->cw[t] = elgamal_encrypt(key, zero);
+    }
+  }
+
+  mpz_add(x, x, v);
+  r2->w = elgamal_encrypt(key, x);
+  for (size_t t = 0; t < 160; t++) {
+    if (mpz_tstbit(key.sk, t)) {
+      r2->cw[t] = elgamal_encrypt(key, x);
+    } else {
+      r2->cw[t] = elgamal_encrypt(key, zero);
+    }
+  }
+
+  mpz_clear(x);
+}
+
+void ssl1_merge(mpz_t rop, const ssl1_t r1, const ssl1_t r2, const elgamal_key_t key)
+{
+  mpz_t rop1, rop2;
+  mpz_inits(rop1, rop2, NULL);
+
+  elgamal_decrypt(rop1, key, r1->w);
+  elgamal_decrypt(rop2, key, r2->w);
+
+  mpz_invert(rop, rop1, p);
+  mpz_mul(rop, rop, rop2);
+  mpz_mod(rop, rop, p);
+
+  mpz_clears(rop1, rop2, NULL);
+}
+
+
+#define strip_size 16
+uint32_t naif_convert(mpz_t n)
+{
+  uint32_t i;
+  mpz_t t;
+  mpz_init_set_ui(t, 1);
+  mpz_mul_2exp(t, t, 1536-strip_size);
+
+
+  for (i = 0; mpz_cmp(n, t) > -1; i++) {
+    mpz_mul_2exp(n, n, 1);
+    mpz_mod(n, n, p);
+  }
+
+  mpz_clear(t);
+  return i;
+}
+
+void hss_mul(mpz_t rop, const ssl1_t sl1, const ssl2_t sl2)
+{
+  mpz_t tmp;
+  mpz_init(tmp);
+
+  mpz_sub(tmp, q, sl2->cx);
+  mpz_powm(tmp, sl1->w.c1, tmp, p);
+
+  mpz_powm(rop, sl1->w.c2, sl2->x, p);
+  mpz_mul(rop, rop, tmp);
+  mpz_mod(rop, rop, p);
+
+  const uint32_t converted = naif_convert(rop);
+  mpz_set_ui(rop, converted);
+
+  mpz_clear(tmp);
+}
+
+int main()
+{
+  /* set up entropy, prime modulus etc. */
+  mpz_entropy_init();
+  hss_init();
+
+  mpz_t test;
+  mpz_init(test);
+
+  /* test elgamal */
+  elgamal_key_t key = elgamal_keygen();
+  //elgamal_cipher_t c = elgamal_encrypt(key, sk);
+  //elgamal_decrypt(test, key, c);
+  //assert(!mpz_cmp(sk, test));
+
+
+  /* end test */
+
+  mpz_t x;
+  mpz_t y;
+
+  mpz_init_set_ui(x, 0);
+  //mpz_rrandomb(x, _rstate, 1);
+  mpz_init_set_ui(y, 1);
+  //mpz_urandomb(y, _rstate, 1);
+
+  /* attempt to create a secret share */
+  ssl1_t r1, r2;
+  ssl2_t s1, s2;
+  mpz_t t1, t2;
+
+  ssl1_init(r1);
+  ssl1_init(r2);
+  ssl2_init(s1);
+  ssl2_init(s2);
+  mpz_inits(t1, t2, NULL);
+
+
+  INIT_TIMEIT();
+
+  for (int i = 0; i < 1e1; i++) {
+
+    ssl1_share(r1, r2, y, key);
+    ssl2_share(s1, s2, x, key.sk);
+
+    ssl2_merge(test, s1, s2);
+    assert(!mpz_cmp(test, x));
+    ssl1_merge(test, r1, r2, key);
+    assert(!mpz_cmp_ui(test, 2));
+
+    START_TIMEIT();
+    hss_mul(t1, r1, s1);
+    END_TIMEIT();
+    hss_mul(t2, r2, s2);
+    ssl2_merge(test, s1, s2);
+    //gmp_printf("%Zd %Zd\n", s1, s2);
+    assert(!mpz_cmp_ui(test, 0));
+  }
+
+  printf(TIMEIT_FORMAT "\n", GET_TIMEIT());
+  ssl2_clear(s1);
+  ssl2_clear(s2);
+  ssl1_clear(r1);
+  ssl1_clear(r2);
+
+  mpz_clears(t1, t2, NULL);
+
+  mpz_clears(x, y, NULL);
+  mpz_clears(key.sk, key.pk, NULL);
+  hss_del();
+  return 0;
+}

+ 12 - 0
src/rms.h

@@ -0,0 +1,12 @@
+#pragma once
+#include <stdint.h>
+
+#include <gmp.h>
+
+#include "entropy.h"
+
+
+//#define ssl2_init(s) mpz_init2(s, 192)
+//#define ssl2_del(s) mpz_clear(s)
+
+//void fbprecompute(ssl1_t *pb);

+ 18 - 0
src/timeit.h

@@ -0,0 +1,18 @@
+#include <sys/time.h>
+
+#define INIT_TIMEIT()                           \
+  struct timeval __start, __end;                \
+  double __sdiff = 0, __udiff = 0
+
+#define START_TIMEIT()                          \
+  gettimeofday(&__start, NULL)
+
+#define END_TIMEIT()                                                    \
+  gettimeofday(&__end, NULL);                                           \
+  __sdiff += (__end.tv_sec - __start.tv_sec);                           \
+  __udiff += (__end.tv_usec - __start.tv_usec)
+
+#define GET_TIMEIT()                            \
+  __sdiff + __udiff * 1e-6
+
+#define TIMEIT_FORMAT "%lf"