Horde_Pgp_Crypt_DSA::sign PHP Method

sign() public method

DSA sign.
public sign ( string $message, string $hash_alg ) : array
$message string Message.
$hash_alg string Hash algorithm.
return array r,s key
    public function sign($message, $hash_alg)
    {
        $hash = new Crypt\Hash($hash_alg);
        $zero = new BigInteger();
        $g = new BigInteger($this->_key->key['g'], 256);
        $p = new BigInteger($this->_key->key['p'], 256);
        $q = new BigInteger($this->_key->key['q'], 256);
        $x = new BigInteger($this->_key->key['x'], 256);
        $bigint_hash = new BigInteger($hash->hash($message), 256);
        while (true) {
            $k = self::randomNumber($q);
            $r_base = $g->modPow($k, $p)->divide($q);
            $r = $r_base[1];
            if ($r->compare($zero) == 0) {
                continue;
            }
            // compute H(m) + (x*r)
            $x_mul_r_base = $x->multiply($r)->divide($q);
            $x_mul_r = $x_mul_r_base[1];
            $bh = clone $bigint_hash;
            $message_dep_base = $bh->add($x_mul_r)->divide($q);
            $message_dep = $message_dep_base[1];
            // compute s
            $k_modInv = $k->modInverse($q);
            $k_modInv_mul = $k_modInv->multiply($message_dep);
            $s_base = $k_modInv_mul->divide($q);
            $s = $s_base[1];
            if ($s->compare($zero) != 0) {
                // r and s are non-zero, we can continue
                break;
            }
        }
        return array('r' => $r->toBytes(), 's' => $s->toBytes());
    }

Usage Example

Example #1
0
 /**
  */
 public function sign($text, $key, $mode, $opts = array())
 {
     $rsa = new OpenPGP_Crypt_RSA($key->message);
     $pkey = $rsa->key();
     $text = $this->_getMessageOb($text)->packets[0];
     switch ($pkey->algorithm) {
         case 1:
         case 2:
         case 3:
             // RSA
             $hash = $opts['sign_hash'] ?: 'SHA256';
             $result = $rsa->sign($text, $hash);
             break;
         case 17:
             // DSA; use SHA1 by default, since that is what DSA/DSS was
             // designed for.
             $hash = $opts['sign_hash'] ?: 'SHA1';
             $sig = new OpenPGP_SignaturePacket($text, 'DSA', $hash);
             $sig->hashed_subpackets[] = new OpenPGP_SignaturePacket_IssuerPacket(substr($pkey->fingerprint, -16));
             $dsa = new Horde_Pgp_Crypt_DSA($pkey);
             $sig->sign_data(array('DSA' => array($hash => function ($data) use($dsa, $hash) {
                 return $dsa->sign($data, $hash);
             })));
             $result = new OpenPGP_Message(array($sig, $text));
             break;
     }
     switch ($mode) {
         case 'clear':
             $sm = new Horde_Pgp_Element_SignedMessage(new OpenPGP_Message(array($result[1], $result[0])));
             $sm->headers['Hash'] = $hash;
             return $sm;
         case 'detach':
             foreach ($result as $val) {
                 if ($val instanceof OpenPGP_SignaturePacket) {
                     return new Horde_Pgp_Element_Signature(new OpenPGP_Message(array($val)));
                 }
             }
             break;
         case 'message':
             return new Horde_Pgp_Element_Message($this->_compressMessageOb($result, $opts['compress']));
     }
 }