Ejemplo n.º 1
0
  bool LRSPublicKey::Verify(const QByteArray &data, const LRSSignature &sig) const
  {
    if(!sig.IsValid()) {
      qDebug() << "Invalid signature";
      return false;
    }

    if(sig.SignatureCount() != GetKeys().count()) {
      qDebug() << "Incorrect amount of keys used to generate signature.";
      return false;
    }

    CppHash hash;
    hash.Update(GetGroupGenerator().GetByteArray());
    hash.Update(sig.GetTag().GetByteArray());
    hash.Update(data);
    QByteArray precompute = hash.ComputeHash();

    Integer tcommit = sig.GetCommit1();

    QVector<Integer> keys = GetKeys();
    for(int idx = 0; idx < keys.count(); idx++) {
      Integer z_p = (GetGenerator().Pow(sig.GetSignature(idx), GetModulus()) *
          _keys[idx].Pow(tcommit, GetModulus())) % GetModulus();
      Integer z_pp = (GetGroupGenerator().Pow(sig.GetSignature(idx), GetModulus()) *
          sig.GetTag().Pow(tcommit, GetModulus())) % GetModulus();

      hash.Update(precompute);
      hash.Update(z_p.GetByteArray());
      hash.Update(z_pp.GetByteArray());
      tcommit = Integer(hash.ComputeHash()) % GetSubgroup();
    }

    return tcommit == sig.GetCommit1();
  }
Ejemplo n.º 2
0
  QByteArray CppDiffieHellman::ProveSharedSecret(const QByteArray &remote_pub) const
  {
    // For modular arithmetic in our DH group
    CryptoPP::Integer modulus = _dh_params.GetGroupParameters().GetModulus();
    CryptoPP::Integer generator = _dh_params.GetGroupParameters().GetGenerator();

    // Arithmetic modulo N
    CryptoPP::ModularArithmetic mod_arith(modulus);
    // Arithmetic modulo phi(N) = N-1
    CryptoPP::ModularArithmetic mod_arith_phi(modulus-1);


    CppHash hash;
    CppDiffieHellman rand_key;

    // A random value v in the group Z_q
    QByteArray value_bytes = rand_key.GetPrivateComponent();
    CppIntegerData value(value_bytes);

    // g  -- the group generator
    QByteArray gen = CppIntegerData(generator).GetByteArray();

    // g^a  -- where a is the prover's secret
    QByteArray prover_pub = GetPublicComponent();

    // g^b  -- where b is the other guy's secret
    QByteArray other_pub = remote_pub;

    // g^(ab)  -- Where a is the prover's secret
    QByteArray dh_secret = GetSharedSecret(other_pub);

    // t_1 = g^v
    CryptoPP::Integer commit_1_int = mod_arith.Exponentiate(generator, value.GetCryptoInteger());
    QByteArray commit_1 = CppIntegerData(commit_1_int).GetByteArray();

    // t_2 = (g^b)^v  -- Where b is the other guy's secret
    QByteArray commit_2 = rand_key.GetSharedSecret(other_pub);

    // c = HASH(g, g^a, g^b, g^ab, t_1, t_2)
    QByteArray challenge_bytes = hash.ComputeHash(gen + prover_pub + other_pub + dh_secret + commit_1 + commit_2);
    CppIntegerData challenge_data(challenge_bytes);
    CryptoPP::Integer challenge = challenge_data.GetCryptoInteger();

    // a = prover secret 
    CryptoPP::Integer prover_priv = CppIntegerData(GetPrivateComponent()).GetCryptoInteger();

    // prod = c*a mod n
    CryptoPP::Integer product_ca = mod_arith_phi.Multiply(challenge, prover_priv);

    // r = v - ca mod n
    CryptoPP::Integer response = mod_arith_phi.Subtract(value.GetCryptoInteger(), product_ca);
    CppIntegerData response_data(response);

    // TEST
    CryptoPP::Integer commit_1p = mod_arith.CascadeExponentiate(generator, 
        response, CppIntegerData(prover_pub).GetCryptoInteger(), challenge);

    // Get encoded version of data
    QByteArray challenge_enc = challenge_data.GetByteArray();
    QByteArray response_enc = response_data.GetByteArray();

    // The header is 3 4-byte lengths
    QByteArray header(ZeroKnowledgeProofHeaderSize, 0); 
    int len_dh_secret = dh_secret.count();
    int len_challenge = challenge_enc.count();
    int len_response = response_enc.count();
    
    Utils::Serialization::WriteInt(len_dh_secret, header, 0);
    Utils::Serialization::WriteInt(len_challenge, header, 4);
    Utils::Serialization::WriteInt(len_response, header, 8);

    // We return (dh_secret, challenge, response)
    return header + dh_secret + challenge_enc + response_enc;
  }
Ejemplo n.º 3
0
  QByteArray CppDiffieHellman::VerifySharedSecret(const QByteArray &prover_pub,
      const QByteArray &remote_pub, const QByteArray &proof) const
  {
    // For modular arithmetic in our DH group
    CryptoPP::Integer modulus = _dh_params.GetGroupParameters().GetModulus();
    CryptoPP::Integer generator = _dh_params.GetGroupParameters().GetGenerator();
    CryptoPP::ModularArithmetic mod_arith(modulus);

    CppHash hash;

    QByteArray header = proof.mid(0, ZeroKnowledgeProofHeaderSize);
    QByteArray body = proof.mid(ZeroKnowledgeProofHeaderSize);

    int len_dh_secret = Utils::Serialization::ReadInt(header, 0);
    if(len_dh_secret < 1) return QByteArray();

    int len_challenge = Utils::Serialization::ReadInt(header, 4);
    if(len_challenge < 1) return QByteArray();

    int len_response = Utils::Serialization::ReadInt(header, 8);
    if(len_response < 1) return QByteArray();

    if(proof.size() < (ZeroKnowledgeProofHeaderSize+len_dh_secret+len_challenge+len_response)) {
      return QByteArray();
    }

    // Recover byte arrays of integers
    int offset = 0;
    QByteArray bytes_dh_secret = body.mid(offset, len_dh_secret);
    offset += len_dh_secret;
    QByteArray bytes_challenge = body.mid(offset, len_challenge);
    offset += len_challenge;
    QByteArray bytes_response = body.mid(offset, len_response);
   
    CppIntegerData dh_secret(bytes_dh_secret);
    CppIntegerData challenge(bytes_challenge);
    CppIntegerData response(bytes_response);

    // commit'_1 = (g^r) * (g^a)^c
    // commit'_1 = (g^r) * (public_key_a)^challenge
    CppIntegerData public_key_a(prover_pub);
    CryptoPP::Integer commit_1 = mod_arith.CascadeExponentiate(CppIntegerData(generator).GetCryptoInteger(), 
        response.GetCryptoInteger(), public_key_a.GetCryptoInteger(), challenge.GetCryptoInteger());

    // commit'_2 = (g^b)^r * (g^ab)^c
    // commit'_2 = (public_key_b)^response * (dh_secret)^challenge

    CppIntegerData public_key_b(remote_pub);
    CryptoPP::Integer commit_2 = mod_arith.CascadeExponentiate(public_key_b.GetCryptoInteger(), 
        response.GetCryptoInteger(), dh_secret.GetCryptoInteger(), challenge.GetCryptoInteger());

    // Group generator g
    QByteArray gen = CppIntegerData(generator).GetByteArray();

    // HASH(g, g^a, g^b
    QByteArray expected_challenge = hash.ComputeHash(gen + prover_pub + remote_pub + 
        bytes_dh_secret + CppIntegerData(commit_1).GetByteArray() + CppIntegerData(commit_2).GetByteArray());

    if(bytes_challenge == expected_challenge) {
      return bytes_dh_secret;
    } else {
      return QByteArray();
    }
  }