bool
paillier_pub::encrypt (crypt_ctext *c, const bigint &msg, bool recover) const 
{
  assert (c);
  assert (c->type == CRYPT_PAILLIER);

  if (msg >= n) {
    warn << "paillier_pub::encrypt: input too large [m " << msg.nbits () 
	 << " n " << n.nbits () << "]\n";
    return false;
  }

  bigint &m = *c->paillier;

  bigint r;
  do r = random_zn (n);
  while (r == 0);

  if (fast)
    // g^(nr) mod n^2
    m = powm (gn, r, nsq);
  else
    // r^n mod n^2
    m = powm (r, n, nsq);

  // g^m mod n^2
  // r^n g^m mod n^2  OR  g^{m+nr} mod n^2
  m *= powm (g, msg, nsq);
  m %= nsq;
  return true;
}
Example #2
0
Values encrypt(const MPI & data, const Values & pub){
    RNG::BBS(static_cast <MPI> (static_cast <unsigned int> (now()))); // seed just in case not seeded
    MPI k = bintompi(RNG::BBS().rand(bitsize(pub[0])));
    k %= pub[0];
    MPI r, s;
    r = powm(pub[1], k, pub[0]);
    s = powm(pub[2], k, pub[0]);
    return {r, (data * s) % pub[0]};
}
Example #3
0
Values new_public(const uint32_t & L, const uint32_t & N){
//    L = 1024, N = 160
//    L = 2048, N = 224
//    L = 2048, N = 256
//    L = 3072, N = 256
    RNG::BBS(static_cast <MPI> (static_cast <unsigned int> (now()))); // seed just in case not seeded

    // random prime q
    MPI q = bintompi("1" + RNG::BBS().rand(N - 1));
    q = nextprime(q);
    while (bitsize(q) > N){
        q = bintompi("1" + RNG::BBS().rand(N - 1));
        q = nextprime(q);
    }

    // random prime p = kq + 1
    MPI p = bintompi("1" + RNG::BBS().rand(L - 1));                   // pick random starting point
    p = ((p - 1) / q) * q + 1;                                        // set starting point to value such that p = kq + 1 for some k, while maintaining bitsize
    while (!knuth_prime_test(p, 25)){
        p += q;
    }

    // generator g with order q
    MPI g = 1, h = 1;
    MPI exp = (p - 1) / q;
    while (g == 1){
        h++;
        g = powm(h, exp, p);
    }

    return {p, q, g};
}
Example #4
0
Values sign(const MPI & data, const Values & pri, const Values & pub, MPI k){
    RNG::BBS(static_cast <MPI> (static_cast <unsigned int> (now()))); // seed just in case not seeded

    bool set_k = (k == 0);

    MPI r = 0, s = 0;
    while ((r == 0) || (s == 0)){
        // 0 < k < q
        if ( set_k ) {
            k = bintompi(RNG::BBS().rand(bitsize(pub[1])));
            k %= pub[1];
        }

        // r = (g^k mod p) mod q
        r = powm(pub[2], k, pub[0]);
        r %= pub[1];

        // if r == 0, don't bother calculating s
        if (r == 0){
            continue;
        }

        // s = k^-1 (m + x * r) mod q
        s = invert(k, pub[1]);
        s *= data + pri[0] * r;
        s %= pub[1];
    }

    return {r, s};
}
Example #5
0
Values keygen(Values & pub){
    RNG::BBS(static_cast <MPI> (static_cast <unsigned int> (now()))); // seed just in case not seeded

    MPI x = 0;
    std::string test = "testing testing 123"; // a string to test the key with, just in case the key doesn't work for some reason
    unsigned int bits = bitsize(pub[1]) - 1;
    while (true){
        // 0 < x < q
        while ((x == 0) || (pub[1] <= x)){
            x = bintompi(RNG::BBS().rand(bits));
        }

        // y = g^x mod p
        MPI y;
        y = powm(pub[2], x, pub[0]);

        // public key = p, q, g, y
        // private key = x
        pub.push_back(y);

        // check that this key works
        Values rs = sign(test, {x}, pub);

        // if it works, break
        if (verify(test, rs, pub)){
            break;
        }

        pub.pop_back();
    }

    return {x};
}
Example #6
0
int main()
{
    std::cout << pow(3, 10) << '\n';
    std::cout << powm(7, 99, 100) << '\n';

    return 0;
}
Example #7
0
std::string decrypt(const Values & c, const Values & pri, const Values & pub){
    MPI s, m;
    s = powm(c[0], pri[0], pub[0]);
    m = invert(s, pub[0]);
    m *= c[1];
    m %= pub[0];
    return mpitoraw(m);
}
void
paillier_pub::init ()
{
  nsq = n;
  mpz_square (&nsq, &n);

  if (fast)
    gn = powm (g, n, nsq);
}
Example #9
0
inline typename enable_if_c<is_integral<I1>::value && is_signed<I2>::value && is_integral<I3>::value, I1>::type
   powm(const I1& a, I2 b, I3 c)
{
   if(b < 0)
   {
      BOOST_THROW_EXCEPTION(std::runtime_error("powm requires a positive exponent."));
   }
   return powm(a, static_cast<typename make_unsigned<I2>::type>(b), c);
}
// Resulting ciphertext is msg's corresponding plaintext * constant
// ctext = ctext^const ==> ptext = const * ptext 
void
paillier_pub::mult (crypt_ctext *c, const crypt_ctext &msg, const bigint &cons) const 
{
  assert (c);
  assert (c->type  == CRYPT_PAILLIER);
  assert (msg.type == CRYPT_PAILLIER);

  *c->paillier = powm (*msg.paillier, cons, nsq);
}
Example #11
0
void
fips186_gen::gen_g (bigint *g, const bigint &p, const bigint &q)
{
  bigint e = (p - 1) / q;
  bigint h;
  bigint p_3 = p - 3;
 
  do h = random_zn (p_3);
  while ((*g = powm (++h, e, p)) == 1);
}
Example #12
0
// Computes (exponent_le32 * 2^doublings) % group_order
boost::multiprecision::cpp_int compute_exponent(const bytestring &exponent_le32, uint64_t doublings)
{
    boost::multiprecision::cpp_int pow(doublings);
    boost::multiprecision::cpp_int mod("0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed"); // group order
    boost::multiprecision::cpp_int base(2);
    boost::multiprecision::cpp_int result = powm(base, pow, mod);
    result = result * le32_to_cpp_int(exponent_le32);
    result = result % mod;
    return result;
}
Example #13
0
Values keygen(unsigned int bits){
    RNG::BBS(static_cast <MPI> (static_cast <unsigned int> (now()))); // seed just in case not seeded

    bits /= 5;
    // random prime q - only used for key generation
    MPI q = bintompi(RNG::BBS().rand(bits));
    q = nextprime(q);
    while (bitsize(q) > bits){
        q = bintompi(RNG::BBS().rand(bits));
        q = nextprime(q);
    }
    bits *= 5;

    // random prime p = kq + 1
    MPI p = bintompi("1" + RNG::BBS().rand(bits - 1));                // pick random starting point
    p = ((p - 1) / q) * q + 1;                                        // set starting point to value such that p = kq + 1 for some k, while maintaining bitsize
    while (!knuth_prime_test(p, 25)){
        p += q;
    }

    // generator g with order p
    MPI g = 1;
    MPI h = 1;
    MPI exp = (p - 1) / q;
    while (g == 1){
        g = powm(++h, exp, p);
    }

    // 0 < x < p
    MPI x = 0;
    while ((x == 0) || (p <= x)){
        x = bintompi(RNG::BBS().rand(bits));
    }

    // y = g^x mod p
    MPI y;
    y = powm(g, x, p);

    return {p, g, y, x};
}
    void t5()
    {
        //
        // Now integer functions:
        //
        ref_type z1, z2;
        test_type t1, t2;
        divide_qr(a, b, z1, z2);
        divide_qr(a1, b1, t1, t2);
        BOOST_TEST_EQ(z1.str(), t1.str());
        BOOST_TEST_EQ(z2.str(), t2.str());
        BOOST_TEST_EQ(integer_modulus(a, si), integer_modulus(a1, si));
        BOOST_TEST_EQ(lsb(a), lsb(a1));

        for(unsigned i = 0; i < 1000; i += 13)
        {
            BOOST_TEST_EQ(bit_test(a, i), bit_test(a1, i));
        }
        // We have to take care that our powers don't grow too large, otherwise this takes "forever",
        // also don't test for modulo types, as these may give a different result from arbitrary
        // precision types:
        BOOST_TEST_EQ(ref_type(pow(d, ui % 19)).str(), test_type(pow(d1, ui % 19)).str());
        BOOST_TEST_EQ(ref_type(powm(a, b, c)).str(), test_type(powm(a1, b1, c1)).str());
        BOOST_TEST_EQ(ref_type(powm(a, b, ui)).str(), test_type(powm(a1, b1, ui)).str());
        BOOST_TEST_EQ(ref_type(powm(a, ui, c)).str(), test_type(powm(a1, ui, c1)).str());
    }
Example #15
0
bool verify(const MPI & data, const Values & sig, const Values & pub){
    // 0 < r < q or 0 < s < q
    if (!((0 < sig[0]) && (sig[0] < pub[1])) & !((0 < sig[0]) && (sig[1] < pub[1]))){
        return false;
    }
    // w = s^-1 mod q
    MPI w = invert(sig[1], pub[1]);

    // u1 = H(m) * w mod q
    MPI u1 = (data * w) % pub[1];

    // u2 = r * w mod q
    MPI u2 = (sig[0] * w) % pub[1];

    // v = ((g ^ u1 * y ^ u2) mod p) mod q
    MPI g, y;
    g = powm(pub[2], u1, pub[0]);
    y = powm(pub[3], u2, pub[0]);

    // check v == r
    return ((((g * y) % pub[0]) % pub[1]) == sig[0]);
}
// Calculate fast decryption with chinese remainder and pre-computed values
void
paillier_priv::D (bigint &m, const bigint &msg) const
{
#if _PAILLIER_CRT_
  // mq = Lq (msg^a mod q^2) hq mod q
  bigint mq;
  if (fast)
    mq = powm (msg, a, qsq);
  else
    mq = powm (msg, q1, qsq);

  // Compute Lq (m)
  mq -= 1;
  mq *= lq;
  mq %= two_q;
  m  %= q;

  mq *= hq;
  mq %= q;

  // mp = Lp (msg^a mod p^2) hp mod p
  if (fast)
    m = powm (msg, a, psq);
  else 
    m = powm (msg, p1, psq);

  // Compute L_p(m)
  m -= 1;
  m *= lp;
  m %= two_p;
  m %= p;

  m *= hp;
  m %= p;

  // Recombine modulo residues
  CRT (m, mq);

#else /* PAILLIER_CRT */

  if (fast)
    m = powm (msg, a, nsq);
  else
    m = powm (msg, k, nsq);

  m -= 1;
  m *= ln;
  m %= two_n;
  m %= n;

  m *= hn;
  m %= n;

#endif
}
static void 
paillier_gen (const bigint &p, const bigint &q, const bigint &n, 
	      const bigint &a, bigint &g, bigint &k)
{
  bigint p1 = p - 1;
  bigint q1 = q - 1;
  
  bigint kgcd;
  mpz_gcd (&kgcd, &p1, &q1);
  k  = p1 * q1;
  k /= kgcd;
    
  if (!p.probab_prime (5) || !q.probab_prime (5) || !a.probab_prime (5))
    fatal ("paillier_keygen: failed primality test\n");
  if ((k % a) != 0)
    fatal << "paillier_keygen: failed div test: " << (k % a) << "\n";
  
  g = powm (2, (k/a), n); 
}
Example #18
0
int
decrypt_mpz_d(mpz_t m, mpz_t d, const char *n_str, const char *c_str)
{
    int rc = 0;
    mpz_t n, c;

    rc += mpz_init_set_str(n, n_str, 0);
    rc += mpz_init_set_str(c, c_str, 0);
    if (rc != 0) {
        fprintf(stderr, "Invalid number argument\n");
        rc = 1;
        goto cleanup;
    }

    powm(m, c, d, n);
cleanup:
    mpz_clear(n);
    mpz_clear(c);
    return rc;
}
void
paillier_priv::init ()
{
  assert (p < q);
  psq = p;
  mpz_square (&psq, &p);

  qsq = q;
  mpz_square (&qsq, &q);

  p1 = p - 1;
  q1 = q - 1;

  if (!fast) {
    bigint kgcd;
    mpz_gcd (&kgcd, &p1, &q1);
    k  = p1 * q1;
    k /= kgcd;
  }

#if _PAILLIER_CRT_
  rp = invert (q, p);
  rq = invert (p, q);

  two_p = pow (2, p.nbits ());
  two_q = pow (2, q.nbits ());

  lp = invert (p, two_p);
  lq = invert (q, two_q);

  if (fast) {
    hp  = powm (g, a, psq);
    hq  = powm (g, a, qsq);
  }
  else {
    hp  = powm (g, p1, psq);
    hq  = powm (g, q1, qsq);
  }
  hp -= 1;
  hp *= lp;
  hp %= two_p;
  hp  = invert (hp, p);

  hq -= 1;
  hq *= lq;
  hq %= two_q;
  hq  = invert (hq, q);

#else  /* PAILLIER_CRT */

  two_n = pow (2, n.nbits ());
  ln  = invert (n, two_n);

  if (fast) 
    hn  = powm (g, a, nsq);
  else
    hn  = powm (g, k, nsq);

  hn -= 1;
  hn *= ln;
  hn %= two_n;
  hn  = invert (hn, n);
#endif
}
Example #20
0
Int RSA::encrypt(std::pair<Int, Int> pk, Int message){
	//modexp(m, pk)
	return powm(message, pk.second, pk.first);
}
Example #21
0
int
main (int argc, char **argv)
{
    random_update ();

    bigint m, m2, r, r2, ri, s1, s2;
    montgom b;

    for (int i = 120; i < 162; i++) {
        int res = 0;
        m = random_bigint (i);
        m.setbit (0, 1);
        b.set (m);
        m2 = m * b.getr ();
        for (int j = i - 33; j <= 2 * i; j++) {
            r = random_zn (m2);
            r.trunc (j);
            s1 = mod (r * b.getri (), m);
            //s2 = b.mreduce (r);
            b.mpz_mreduce (&s2, &r);
            if (s1 != s2) {
                res |= 1;
                int sz = mpz_sizeinbase (&s1, 16);
                panic << "mreduce failed\n"
                      << " m = " << m << "\n"
                      << " r = " << r << "\n"
                      << "     " << s1 << "\n  != " << s2 << "\n"
                      << "    ["
                      << strbuf ("%*s", sz, bigint (abs (s1 - s2)).cstr ())
                      << "]\n";
            }
        }

        // r = s1;
        r = random_zn (m);
        r2 = random_zn (m);
        assert (r < m && r2 < m);

        s1 = mod (r * r2 * b.getri (), m);
        b.mpz_mmul (&s2, &r, &r2);
        if (s1 != s2) {
            res |= 2;
            int sz = mpz_sizeinbase (&s1, 16);
            panic << "mmul failed\n"
                  << " m = " << m << "\n"
                  << " r = " << r << "\n"
                  << "     " << s1 << "\n  != " << s2 << "\n"
                  << "    ["
                  << strbuf ("%*s", sz, bigint (abs (s1 - s2)).cstr ())
                  << "]\n";
        }

        s1 = powm (r, r2, m);
        b.mpz_powm (&s2, &r, &r2);
        if (s1 != s2) {
            res |= 4;
            int sz = mpz_sizeinbase (&s1, 16);
            panic << "powm failed\n"
                  << " m = " << m << "\n"
                  << " r = " << r << "\n"
                  << "     " << s1 << "\n  != " << s2 << "\n"
                  << "    ["
                  << strbuf ("%*s", sz, bigint (abs (s1 - s2)).cstr ())
                  << "]\n";
        }

#if 0
        warn ("%s mreduce.. %d\n", (res&1) ? "fail" : "ok", i);
        warn ("%s mmul.. %d\n", (res&2) ? "fail" : "ok", i);
        warn ("%s powm.. %d\n", (res&4) ? "fail" : "ok", i);
#endif
    }

    return 0;
}
Example #22
0
Int RSA::decrypt(std::pair<Int, Int> sk, Int ciphertext){
	return powm(ciphertext, sk.second, sk.first);
}
Example #23
0
void BBS::r_number(){
    state = powm(state, two, m);
}