Exemple #1
0
 CryptoPP::ECP::Point Sum (const CryptoPP::ECP::Point& p1, const CryptoPP::ECP::Point& p2) const
 {
     CryptoPP::Integer m = d*p1.x*p2.x*p1.y*p2.y,
     x = a_times_b_mod_c (p1.x*p2.y + p2.x*p1.y, (CryptoPP::Integer::One() + m).InverseMod (q), q),
     y = a_times_b_mod_c (p1.y*p2.y + p1.x*p2.x, (CryptoPP::Integer::One() - m).InverseMod (q), q);
     return CryptoPP::ECP::Point {x, y};
 }
  bool verify(CryptoPP::ECPPoint Q, byte *message, unsigned message_length, CryptoPP::Integer r, CryptoPP::Integer s){
		auto ec = common::ec_parameters().GetCurve();
	  auto G = common::ec_parameters().GetSubgroupGenerator();
	  auto n = common::ec_parameters().GetGroupOrder();

    Integer z = hash_m_to_int(message, message_length, n.ByteCount());
    // verify
    if (Q == ec.Identity()){
      cerr << "Q == O" << endl;
      return false;
    }
    if (!(ec.Multiply(n, Q) == ec.Identity())){
      cerr << "n x Q != O" << endl;
      return false;
    }
    if (r <= 0 || r >= n){
      cerr << "incorrect r" << endl;
      return false;
    } 
    if (s <= 0 || s >= n){
      cerr << "incorrect s" << endl;
      return false;
    } 
    Integer w = s.InverseMod(n);
    Integer u1 = a_times_b_mod_c(z, w, n);
    Integer u2 = a_times_b_mod_c(r, w, n);
    ECPPoint P2 = ec.Add(ec.Multiply(u1, G), ec.Multiply(u2, Q));

    if (P2.x != r){
      cerr << "P2.x != r" << endl;
      return false;
    }
    return true;
  }
	void B::cont_sig(ECPPoint Ks, Integer cs, byte *m, unsigned m_len){
		kb.Randomize(common::rng(), Integer::One(), n-1);
		K = ec.Multiply(kb, Ks);
		r = K.x % n;
		if (r == 0)
			throw ProtocolException("r == 0");

		Integer hi = hash_m_to_int(m, m_len, n.ByteCount());
		Integer c1 = paillier.enc( a_times_b_mod_c(kb.InverseMod(n), hi, n) );
		Integer t = a_times_b_mod_c(a_times_b_mod_c(kb.InverseMod(n), r, n), db, n);
		Integer c2 = a_times_b_mod_c(c1, a_exp_b_mod_c(cs, t, paillier.get_n2()), paillier.get_n2());
		Integer u(common::rng(), Integer::Zero(), n*n - 1);
		cb = a_times_b_mod_c(c2, paillier.enc(u*n), paillier.get_n2());
	}
vI Commiter::zk_4(const vI &commit_values) {

    if (commit_values.size() != com.K+1) {
        throw ProtocolException("invalid commit_values size");
    }

    for(unsigned i = 1; i <= com.K; ++i) {
        if (!regular_verify(commits[i], commit_values[i])) {
            throw ProtocolException("regular commit didn't verify");
        }
    }

    vI y(com.K+1);
    for(unsigned i = 1; i <= com.K; ++i) {
        Integer yi = a_times_b_mod_c(
                         commit_values[i],
                         a_exp_b_mod_c(2, Integer::Power2(i-1), order),
                         order);
        yi += alpha[i];
        yi %= order;
        y[i] = yi;
    }

    return y;
}
Exemple #5
0
 CryptoPP::Integer RecoverX (const CryptoPP::Integer& y) const
 {
     auto y2 = y.Squared ();
     auto xx = (y2 - CryptoPP::Integer::One())*(d*y2 + CryptoPP::Integer::One()).InverseMod (q); 
     auto x = a_exp_b_mod_c (xx, (q + CryptoPP::Integer (3)).DividedBy (8), q);
     if (!(x.Squared () - xx).Modulo (q).IsZero ())
         x = a_times_b_mod_c (x, I, q);
     if (x.IsOdd ()) x = q - x;
     return x;
 }
vector<bool> Receiver::decode(Integer v) {
    vector<bool> res(com.l);
    for(unsigned i = 0; i < com.l; ++i) {
        res[i] = com.S[i] ^ v.GetBit(0);
        v = a_times_b_mod_c(v, v, com.n);
    }

    if (v != com.u) {
        throw SanityException("v != com.u");
    }
    return res;
}
void Receiver::zk_5(const vI &y) {
    if (y.size() != com.K+1) {
        throw ProtocolException("y size != K+1");
    }

    for(unsigned i = 1; i <= com.K; ++i) {

        Integer zi = a_times_b_mod_c(
                         a_exp_b_mod_c(com.g, y[i], com.n),
                         a_exp_b_mod_c(com.W[i-1].InverseMod(com.n), commit_values[i], com.n),
                         com.n);
        if (zi != zw.first[i]) {
            throw ProtocolException("zi verification failed");
        }

        Integer wi = a_times_b_mod_c(
                         a_exp_b_mod_c(com.W[i-1], y[i], com.n),
                         a_exp_b_mod_c(com.W[i].InverseMod(com.n), commit_values[i], com.n),
                         com.n);
        if (wi != zw.second[i]) {
            throw ProtocolException("wi verification failed");
        }
    }
}
Commitment Commiter::commit(const unsigned K, const vector<bool> &m) {
    unsigned available_primes;
    Integer g, h;
    Integer a0, a, u;
    vector<bool> S;
    vector<Integer> W;
    unsigned l;

    // sanity check on m
    for(bool b: m) {
        if (b != 0 && b != 1) {
            throw SanityException("not binary m");
        }
    }
    l = m.size();

    h = Integer(common::rng(), 2, n-1);
    g = get_g(n, h);
    order = find_order(p, q, g);

    a0 = a_exp_b_mod_c(2, Integer::Power2(K) - l, phi);
    a = a_exp_b_mod_c(2, Integer::Power2(K), phi);
    u = a_exp_b_mod_c(g, a0, n);

    S.resize(l);
    for(unsigned i = 0; i < l; ++i) {
        S[i] = m[i] ^ u.GetBit(0);
        u = a_times_b_mod_c(u, u, n);
    }

    // sanity check on u
    if (u != a_exp_b_mod_c(g, a, n)) {
        throw SanityException("u != g ** a");
    }

    W.resize(K+1);
    for(unsigned i = 0; i <= K; ++i) {
        Integer exp = a_exp_b_mod_c(2, Integer::Power2(i) , phi);
        W[i] = a_exp_b_mod_c(g, exp, n);
    }

    // sanity check on W
    if (W[0] != (g*g % n) || W[1] != (g*g*g*g % n) || W[K] != u) {
        throw SanityException("invalid W");
    }
    com = Commitment(K, n, h, g, u, S, W, m.size());
    return com;
}
vector<bool> Receiver::force_open_smart() {

    Integer v = com.W[com.K-1];

    for(Integer i = 0; i < Integer::Power2(com.K-1) - com.l; ++i) {
        v = a_times_b_mod_c(v, v, com.n);
    }

    Integer u = a_exp_b_mod_c(v, Integer::Power2(com.l), com.n);

    if (u != com.u) {
        throw ProtocolException("u != com.u");
    }

    return decode(v);
}
BinaryData CryptoECDSA::ECMultiplyScalars(BinaryData const & A, 
                                          BinaryData const & B)
{
   // Hardcode the order of the secp256k1 EC group
   static BinaryData N = BinaryData::CreateFromHex(
           "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141");

   CryptoPP::Integer intA, intB, intC, intN;
   intA.Decode(A.getPtr(), A.getSize(), UNSIGNED);
   intB.Decode(B.getPtr(), B.getSize(), UNSIGNED);
   intN.Decode(N.getPtr(), N.getSize(), UNSIGNED);
   intC = a_times_b_mod_c(intA, intB, intN);

   BinaryData C(32);
   intC.Encode(C.getPtr(), 32, UNSIGNED);
   return C;
}
	void S::finish_sig(Integer r, Integer cb){
		this->r = r;
		Integer s2 = paillier.dec(cb) % n;
		s = a_times_b_mod_c(ks.InverseMod(n), s2, n);
		if (s == 0){
			throw ProtocolException("ERR s==0 restart protocol");
		}
    if (s > n - s) {
      s = n - s;
    }

		// bool result = verifier.VerifyMessage(get_data(), get_data_length(), signature, 64);
		bool result = verify(Q, get_data(), get_data_length(), r, s);
		if (!result){
			throw ProtocolException("Invalid signature generated!");
		} else {
    }
	}
/////////////////////////////////////////////////////////////////////////////
// Deterministically generate new private key using a chaincode
// Changed:  added using the hash of the public key to the mix
//           b/c multiplying by the chaincode alone is too "linear"
//           (there's no reason to believe it's insecure, but it doesn't
//           hurt to add some extra entropy/non-linearity to the chain
//           generation process)
SecureBinaryData CryptoECDSA::ComputeChainedPrivateKey(
                                 SecureBinaryData const & binPrivKey,
                                 SecureBinaryData const & chainCode,
                                 SecureBinaryData binPubKey,
                                 SecureBinaryData* multiplierOut)
{
   if(CRYPTO_DEBUG)
   {
      cout << "ComputeChainedPrivateKey:" << endl;
      cout << "   BinPrv: " << binPrivKey.toHexStr() << endl;
      cout << "   BinChn: " << chainCode.toHexStr() << endl;
      cout << "   BinPub: " << binPubKey.toHexStr() << endl;
   }


   if( binPubKey.getSize()==0 )
      binPubKey = ComputePublicKey(binPrivKey);

   if( binPrivKey.getSize() != 32 || chainCode.getSize() != 32)
   {
      LOGERR << "***ERROR:  Invalid private key or chaincode (both must be 32B)";
      LOGERR << "BinPrivKey: " << binPrivKey.getSize();
      LOGERR << "BinPrivKey: (not logged for security)";
      //LOGERR << "BinPrivKey: " << binPrivKey.toHexStr();
      LOGERR << "BinChain  : " << chainCode.getSize();
      LOGERR << "BinChain  : " << chainCode.toHexStr();
   }

   // Adding extra entropy to chaincode by xor'ing with hash256 of pubkey
   BinaryData chainMod  = binPubKey.getHash256();
   BinaryData chainOrig = chainCode.getRawCopy();
   BinaryData chainXor(32);
      
   for(uint8_t i=0; i<8; i++)
   {
      uint8_t offset = 4*i;
      *(uint32_t*)(chainXor.getPtr()+offset) =
                           *(uint32_t*)( chainMod.getPtr()+offset) ^ 
                           *(uint32_t*)(chainOrig.getPtr()+offset);
   }


   // Hard-code the order of the group
   static SecureBinaryData SECP256K1_ORDER_BE = SecureBinaryData().CreateFromHex(
           "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141");
   
   CryptoPP::Integer mult, origPrivExp, ecOrder;
   // A 
   mult.Decode(chainXor.getPtr(), chainXor.getSize(), UNSIGNED);
   // B 
   origPrivExp.Decode(binPrivKey.getPtr(), binPrivKey.getSize(), UNSIGNED);
   // C
   ecOrder.Decode(SECP256K1_ORDER_BE.getPtr(), SECP256K1_ORDER_BE.getSize(), UNSIGNED);

   // A*B mod C will get us a new private key exponent
   CryptoPP::Integer newPrivExponent = 
                  a_times_b_mod_c(mult, origPrivExp, ecOrder);

   // Convert new private exponent to big-endian binary string 
   SecureBinaryData newPrivData(32);
   newPrivExponent.Encode(newPrivData.getPtr(), newPrivData.getSize(), UNSIGNED);

   if(multiplierOut != NULL)
      (*multiplierOut) = SecureBinaryData(chainXor);

   //LOGINFO << "Computed new chained private key using:";
   //LOGINFO << "   Public key: " << binPubKey.toHexStr().c_str();
   //LOGINFO << "   PubKeyHash: " << chainMod.toHexStr().c_str();
   //LOGINFO << "   Chaincode:  " << chainOrig.toHexStr().c_str();
   //LOGINFO << "   Multiplier: " << chainXor.toHexStr().c_str();

   return newPrivData;
}
Exemple #13
0
 virtual IIntegerImpl *Multiply(const IIntegerImpl * const multiplicand,
                                const IIntegerImpl * const modulus) const
 {
     return new CppIntegerImpl(a_times_b_mod_c(m_data,
                               GetData(multiplicand), GetData(modulus)));
 }