perform elliptic curve addition
352079
def add(self, p, q):
        
        if p.iszero():
            return q
        if q.iszero():
            return p

        lft = 0
        # calculate the slope of the intersection line
        if p == q:
            if p.y == 0:
                return self.zero()
            lft = (3 * p.x ** 2 + self.a) / (2 * p.y)
        elif p.x == q.x:
            return self.zero()
        else:
            lft = (p.y - q.y) / (p.x - q.x)

        # calculate the intersection point
        x = lft ** 2 - (p.x + q.x)
        y = lft * (p.x - x) - p.y
        return self.point(x, y)
750345
function ecp_add(R, N1, N2, a, p, l) {
	var x1 = N1[0], y1 = N1[1], z1 = N1[2], x2 = N2[0], y2 = N2[1], z2 = N2[2];
	var xr = R[0], yr = R[1], zr = R[2];
	if (mpn_zero_p(z1, l)) {
		if (mpn_zero_p(z2, l)) {
			mpn_zero(xr, l), mpn_zero(yr, l), mpn_zero(zr, l);
			return R;
		}
		return ecp_copy(R, N2, l);
	}
	if (mpn_zero_p(z2, l)) {
		return ecp_copy(R, N1, l);
	}
	if (mpn_one_p(z2, l)) {
		return ecp_add_aff(R, N1, N2, a, p, l);
	}
	var t0 = _ecp_t0, t1 = _ecp_t1, t2 = _ecp_t2, t3 = _ecp_t3, t4 = _ecp_t4, t5 = _ecp_t5, t6 = _ecp_t6;
	fp_sqr(t0, z1, p, l);
	fp_mul(t1, x2, t0, p, l);
	fp_mul(t2, z1, t0, p, l);
	fp_mul(t0, y2, t2, p, l);
	fp_sqr(t2, z2, p, l);
	fp_mul(t3, x1, t2, p, l);
	fp_mul(t4, z2, t2, p, l);
	fp_mul(t2, y1, t4, p, l);
	if (mpn_cmp(t3, t1, l) == 0) {
		if (mpn_cmp(t2, t0, l) == 0) {
			return ecp_dbl(R, N1, a, p, l);
		}
		mpn_zero(xr, l), mpn_zero(yr, l), mpn_zero(zr, l);
		xr[0] = yr[0] = 1;
		return R;
	}
	fp_sub(t4, t1, t3, p, l);
	fp_sub(t1, t0, t2, p, l);
	fp_sqr(t0, t4, p, l);
	fp_mul(t5, t4, t0, p, l);
	fp_mul(t6, t3, t0, p, l);
	fp_sub(xr, fp_sub(xr, fp_sqr(xr, t1, p, l), t5, p, l), fp_dbl(t0, t6, p, l), p, l);
	fp_sub(yr, fp_mul(yr, t1, fp_sub(t6, t6, xr, p, l), p, l), fp_mul(t0, t2, t5, p, l), p, l);
	fp_mul(zr, t4, fp_mul(t0, z1, z2, p, l), p, l);
	return R;
}
782664
void conservativeIncrement(long e) {
    int hash = spread(Long.hashCode(e));
    int start = (hash & 3) << 2;

    int[] index = new int[4];
    int[] count = new int[4];
    int min = Integer.MAX_VALUE;
    for (int i = 0; i < 4; i++) {
      index[i] = indexOf(hash, i);
      count[i] = (int) ((table[index[i]] >>> ((start + i) << 2)) & 0xfL);
      min = Math.min(min, count[i]);
    }

    if (min == 15) {
      tryReset(false);
      return;
    }

    for (int i = 0; i < 4; i++) {
      if (count[i] == min) {
        incrementAt(index[i], start + i, step);
      }
    }
    tryReset(true);
  }
1163612
function ECDSA({ x, y, d }) {
  if (x.length !== curveLength) throw new TypeError('Public EC Key point X of wrong length')
  if (y.length !== curveLength) throw new TypeError('Public EC Key point Y of wrong length')

  this.x = x
  this.y = y
  this.publicCodePoint = Buffer.concat([Buffer.from([0x04]), x, y])
  if (d) {
    this.d = d
    this.isPrivate = true
  } else {
    this.isPrivate = false
  }
}
822628
function mixkey(seed, key, smear, j) {
  seed += '';                         // Ensure the seed is a string
  smear = 0;
  for (j = 0; j < seed.length; j++) {
    key[lowbits(j)] =
      lowbits((smear ^= key[lowbits(j)] * 19) + seed.charCodeAt(j));
  }
  seed = '';
  for (j in key) { seed += String.fromCharCode(key[j]); }
  return seed;
}
167971
def create(curve, data):
    
    ec_key = libcrypto.EC_KEY_new_by_curve_name(curve.nid)
    if ec_key is None:
        raise PKeyError("EC_KEY_new_by_curvename")
    group = libcrypto.EC_KEY_get0_group(ec_key)
    if group is None:
        raise PKeyError("EC_KEY_get0_group")
    libcrypto.EC_GROUP_set_asn1_flag(group, 1)
    raw_key = libcrypto.BN_new()
    if isinstance(data, int):
        libcrypto.BN_hex2bn(byref(raw_key), hex(data))
    else:
        if raw_key is None:
            raise PKeyError("BN_new")
        if libcrypto.BN_bin2bn(data, len(data), raw_key) is None:
            raise PKeyError("BN_bin2bn")
    ctx = libcrypto.BN_CTX_new()
    if ctx is None:
        raise PKeyError("BN_CTX_new")
    order = libcrypto.BN_new()
    if order is None:
        raise PKeyError("BN_new")
    priv_key = libcrypto.BN_new()
    if priv_key is None:
        raise PKeyError("BN_new")
    if libcrypto.EC_GROUP_get_order(group, order, ctx) <= 0:
        raise PKeyError("EC_GROUP_get_order")
    if libcrypto.BN_nnmod(priv_key, raw_key, order, ctx) <= 0:
        raise PKeyError("BN_nnmod")
    if libcrypto.EC_KEY_set_private_key(ec_key, priv_key) <= 0:
        raise PKeyError("EC_KEY_set_private_key")
    pub_key = libcrypto.EC_POINT_new(group)
    if pub_key is None:
        raise PKeyError("EC_POINT_new")
    if libcrypto.EC_POINT_mul(group, pub_key, priv_key, None, None, ctx) <= 0:
        raise PKeyError("EC_POINT_mul")
    if libcrypto.EC_KEY_set_public_key(ec_key, pub_key) <= 0:
        raise PKeyError("EC_KEY_set_public_key")
    libcrypto.BN_free(raw_key)
    libcrypto.BN_free(order)
    libcrypto.BN_free(priv_key)
    libcrypto.BN_CTX_free(ctx)
    pkey = libcrypto.EVP_PKEY_new()
    if pkey is None:
        raise PKeyError("EVP_PKEY_new")
    if libcrypto.EVP_PKEY_set1_EC_KEY(pkey, ec_key) <= 0:
        raise PKeyError("EVP_PKEY_set1_EC_KEY")
    libcrypto.EC_KEY_free(ec_key)
    return PKey(ptr=pkey, cansign=True)
65993
private void hashMix() {
       a = subtract(a, b); a = subtract(a, c); a = xor(a, c >> 13);
       b = subtract(b, c); b = subtract(b, a); b = xor(b, leftShift(a, 8));
       c = subtract(c, a); c = subtract(c, b); c = xor(c, (b >> 13));
       a = subtract(a, b); a = subtract(a, c); a = xor(a, (c >> 12));
       b = subtract(b, c); b = subtract(b, a); b = xor(b, leftShift(a, 16));
       c = subtract(c, a); c = subtract(c, b); c = xor(c, (b >> 5));
       a = subtract(a, b); a = subtract(a, c); a = xor(a, (c >> 3));
       b = subtract(b, c); b = subtract(b, a); b = xor(b, leftShift(a, 10));
       c = subtract(c, a); c = subtract(c, b); c = xor(c, (b >> 15));
     }
1192336
function _convertPrivateKey($n, $e, $d, $primes, $exponents, $coefficients)
    {
        $signed = $this->privateKeyFormat != self::PRIVATE_FORMAT_XML;
        $num_primes = count($primes);
        $raw = array(
            'version' => $num_primes == 2 ? chr(0) : chr(1), // two-prime vs. multi
            'modulus' => $n->toBytes($signed),
            'publicExponent' => $e->toBytes($signed),
            'privateExponent' => $d->toBytes($signed),
            'prime1' => $primes[1]->toBytes($signed),
            'prime2' => $primes[2]->toBytes($signed),
            'exponent1' => $exponents[1]->toBytes($signed),
            'exponent2' => $exponents[2]->toBytes($signed),
            'coefficient' => $coefficients[2]->toBytes($signed)
        );

        // if the format in question does not support multi-prime rsa and multi-prime rsa was used,
        // call _convertPublicKey() instead.
        switch ($this->privateKeyFormat) {
            case self::PRIVATE_FORMAT_XML:
                if ($num_primes != 2) {
                    return false;
                }
                return "<RSAKeyValue>\r\n" .
                       '  <Modulus>' . base64_encode($raw['modulus']) . "</Modulus>\r\n" .
                       '  <Exponent>' . base64_encode($raw['publicExponent']) . "</Exponent>\r\n" .
                       '  <P>' . base64_encode($raw['prime1']) . "</P>\r\n" .
                       '  <Q>' . base64_encode($raw['prime2']) . "</Q>\r\n" .
                       '  <DP>' . base64_encode($raw['exponent1']) . "</DP>\r\n" .
                       '  <DQ>' . base64_encode($raw['exponent2']) . "</DQ>\r\n" .
                       '  <InverseQ>' . base64_encode($raw['coefficient']) . "</InverseQ>\r\n" .
                       '  <D>' . base64_encode($raw['privateExponent']) . "</D>\r\n" .
                       '</RSAKeyValue>';
                break;
            case self::PRIVATE_FORMAT_PUTTY:
                if ($num_primes != 2) {
                    return false;
                }
                $key = "PuTTY-User-Key-File-2: ssh-rsa\r\nEncryption: ";
                $encryption = (!empty($this->password) || is_string($this->password)) ? 'aes256-cbc' : 'none';
                $key.= $encryption;
                $key.= "\r\nComment: " . $this->comment . "\r\n";
                $public = pack(
                    'Na*Na*Na*',
                    strlen('ssh-rsa'),
                    'ssh-rsa',
                    strlen($raw['publicExponent']),
                    $raw['publicExponent'],
                    strlen($raw['modulus']),
                    $raw['modulus']
                );
                $source = pack(
                    'Na*Na*Na*Na*',
                    strlen('ssh-rsa'),
                    'ssh-rsa',
                    strlen($encryption),
                    $encryption,
                    strlen($this->comment),
                    $this->comment,
                    strlen($public),
                    $public
                );
                $public = base64_encode($public);
                $key.= "Public-Lines: " . ((strlen($public) + 63) >> 6) . "\r\n";
                $key.= chunk_split($public, 64);
                $private = pack(
                    'Na*Na*Na*Na*',
                    strlen($raw['privateExponent']),
                    $raw['privateExponent'],
                    strlen($raw['prime1']),
                    $raw['prime1'],
                    strlen($raw['prime2']),
                    $raw['prime2'],
                    strlen($raw['coefficient']),
                    $raw['coefficient']
                );
                if (empty($this->password) && !is_string($this->password)) {
                    $source.= pack('Na*', strlen($private), $private);
                    $hashkey = 'putty-private-key-file-mac-key';
                } else {
                    $private.= Random::string(16 - (strlen($private) & 15));
                    $source.= pack('Na*', strlen($private), $private);
                    $sequence = 0;
                    $symkey = '';
                    while (strlen($symkey) < 32) {
                        $temp = pack('Na*', $sequence++, $this->password);
                        $symkey.= pack('H*', sha1($temp));
                    }
                    $symkey = substr($symkey, 0, 32);
                    $crypto = new AES();

                    $crypto->setKey($symkey);
                    $crypto->disablePadding();
                    $private = $crypto->encrypt($private);
                    $hashkey = 'putty-private-key-file-mac-key' . $this->password;
                }

                $private = base64_encode($private);
                $key.= 'Private-Lines: ' . ((strlen($private) + 63) >> 6) . "\r\n";
                $key.= chunk_split($private, 64);
                $hash = new Hash('sha1');
                $hash->setKey(pack('H*', sha1($hashkey)));
                $key.= 'Private-MAC: ' . bin2hex($hash->hash($source)) . "\r\n";

                return $key;
            default: // eg. self::PRIVATE_FORMAT_PKCS1
                $components = array();
                foreach ($raw as $name => $value) {
                    $components[$name] = pack('Ca*a*', self::ASN1_INTEGER, $this->_encodeLength(strlen($value)), $value);
                }

                $RSAPrivateKey = implode('', $components);

                if ($num_primes > 2) {
                    $OtherPrimeInfos = '';
                    for ($i = 3; $i <= $num_primes; $i++) {
                        // OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo
                        //
                        // OtherPrimeInfo ::= SEQUENCE {
                        //     prime             INTEGER,  -- ri
                        //     exponent          INTEGER,  -- di
                        //     coefficient       INTEGER   -- ti
                        // }
                        $OtherPrimeInfo = pack('Ca*a*', self::ASN1_INTEGER, $this->_encodeLength(strlen($primes[$i]->toBytes(true))), $primes[$i]->toBytes(true));
                        $OtherPrimeInfo.= pack('Ca*a*', self::ASN1_INTEGER, $this->_encodeLength(strlen($exponents[$i]->toBytes(true))), $exponents[$i]->toBytes(true));
                        $OtherPrimeInfo.= pack('Ca*a*', self::ASN1_INTEGER, $this->_encodeLength(strlen($coefficients[$i]->toBytes(true))), $coefficients[$i]->toBytes(true));
                        $OtherPrimeInfos.= pack('Ca*a*', self::ASN1_SEQUENCE, $this->_encodeLength(strlen($OtherPrimeInfo)), $OtherPrimeInfo);
                    }
                    $RSAPrivateKey.= pack('Ca*a*', self::ASN1_SEQUENCE, $this->_encodeLength(strlen($OtherPrimeInfos)), $OtherPrimeInfos);
                }

                $RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);

                if ($this->privateKeyFormat == self::PRIVATE_FORMAT_PKCS8) {
                    $rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA
                    $RSAPrivateKey = pack(
                        'Ca*a*Ca*a*',
                        self::ASN1_INTEGER,
                        "\01\00",
                        $rsaOID,
                        4,
                        $this->_encodeLength(strlen($RSAPrivateKey)),
                        $RSAPrivateKey
                    );
                    $RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
                    if (!empty($this->password) || is_string($this->password)) {
                        $salt = Random::string(8);
                        $iterationCount = 2048;

                        $crypto = new DES();
                        $crypto->setPassword($this->password, 'pbkdf1', 'md5', $salt, $iterationCount);
                        $RSAPrivateKey = $crypto->encrypt($RSAPrivateKey);

                        $parameters = pack(
                            'Ca*a*Ca*N',
                            self::ASN1_OCTETSTRING,
                            $this->_encodeLength(strlen($salt)),
                            $salt,
                            self::ASN1_INTEGER,
                            $this->_encodeLength(4),
                            $iterationCount
                        );
                        $pbeWithMD5AndDES_CBC = "\x2a\x86\x48\x86\xf7\x0d\x01\x05\x03";

                        $encryptionAlgorithm = pack(
                            'Ca*a*Ca*a*',
                            self::ASN1_OBJECT,
                            $this->_encodeLength(strlen($pbeWithMD5AndDES_CBC)),
                            $pbeWithMD5AndDES_CBC,
                            self::ASN1_SEQUENCE,
                            $this->_encodeLength(strlen($parameters)),
                            $parameters
                        );

                        $RSAPrivateKey = pack(
                            'Ca*a*Ca*a*',
                            self::ASN1_SEQUENCE,
                            $this->_encodeLength(strlen($encryptionAlgorithm)),
                            $encryptionAlgorithm,
                            self::ASN1_OCTETSTRING,
                            $this->_encodeLength(strlen($RSAPrivateKey)),
                            $RSAPrivateKey
                        );

                        $RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);

                        $RSAPrivateKey = "-----BEGIN ENCRYPTED PRIVATE KEY-----\r\n" .
                                         chunk_split(base64_encode($RSAPrivateKey), 64) .
                                         '-----END ENCRYPTED PRIVATE KEY-----';
                    } else {
                        $RSAPrivateKey = "-----BEGIN PRIVATE KEY-----\r\n" .
                                         chunk_split(base64_encode($RSAPrivateKey), 64) .
                                         '-----END PRIVATE KEY-----';
                    }
                    return $RSAPrivateKey;
                }

                if (!empty($this->password) || is_string($this->password)) {
                    $iv = Random::string(8);
                    $symkey = pack('H*', md5($this->password . $iv)); // symkey is short for symmetric key
                    $symkey.= substr(pack('H*', md5($symkey . $this->password . $iv)), 0, 8);
                    $des = new TripleDES();
                    $des->setKey($symkey);
                    $des->setIV($iv);
                    $iv = strtoupper(bin2hex($iv));
                    $RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" .
                                     "Proc-Type: 4,ENCRYPTED\r\n" .
                                     "DEK-Info: DES-EDE3-CBC,$iv\r\n" .
                                     "\r\n" .
                                     chunk_split(base64_encode($des->encrypt($RSAPrivateKey)), 64) .
                                     '-----END RSA PRIVATE KEY-----';
                } else {
                    $RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" .
                                     chunk_split(base64_encode($RSAPrivateKey), 64) .
                                     '-----END RSA PRIVATE KEY-----';
                }

                return $RSAPrivateKey;
        }
    }
282903
function bitcount(key, start, end /* req */) {
  var req = typeof arguments[arguments.length - 1] === 'object'
    ? arguments[arguments.length - 1] : null
    , buf = this.getValueBuffer(key, req, true)
    , c = 0
    , count = 0
    , bytecount = 16;

  // no key or empty string
  if(buf === undefined || buf.length === 0) return 0;
  // got start/end range
  if(arguments.length >= 3) {
    if(start < 0) start = buf.length + start;
    if(end < 0) end = buf.length + end;
    if(start < 0) start = 0;
    if(end < 0) end = 0;
    if(end > buf.length) end = buf.length;
  }else{
    start = 0;
    end = buf.length;
  }

  if(start > end) return 0;

  // get the range we are inspecting
  buf = buf.slice(start, end + 1);

  function addBitCount(buf) {
    for(var i = 0;i < buf.length;i++) {
      if(buf[i] & 0x80) count++;
      if(buf[i] & 0x40) count++;
      if(buf[i] & 0x20) count++;
      if(buf[i] & 0x10) count++;
      if(buf[i] & 0x08) count++;
      if(buf[i] & 0x04) count++;
      if(buf[i] & 0x02) count++;
      if(buf[i] & 0x01) count++;
    }
  }

  // leading non-aligned bytes
  var mod = buf.length % bytecount;
  while(c < mod) {
    addBitCount(buf.slice(c, c + 1));
    c++;
  }

  // aligned bytes
  while(c < buf.length) {
    addBitCount(buf.slice(c, c + bytecount));
    c += bytecount;
  }
  return count;
}
739561
function(x, key, pub) {
  if(pub) {
    return x.modPow(key.e, key.n);
  }

  if(!key.p || !key.q) {
    // allow calculation without CRT params (slow)
    return x.modPow(key.d, key.n);
  }

  // pre-compute dP, dQ, and qInv if necessary
  if(!key.dP) {
    key.dP = key.d.mod(key.p.subtract(BigInteger.ONE));
  }
  if(!key.dQ) {
    key.dQ = key.d.mod(key.q.subtract(BigInteger.ONE));
  }
  if(!key.qInv) {
    key.qInv = key.q.modInverse(key.p);
  }

  /* Chinese remainder theorem (CRT) states:

    Suppose n1, n2, ..., nk are positive integers which are pairwise
    coprime (n1 and n2 have no common factors other than 1). For any
    integers x1, x2, ..., xk there exists an integer x solving the
    system of simultaneous congruences (where ~= means modularly
    congruent so a ~= b mod n means a mod n = b mod n):

    x ~= x1 mod n1
    x ~= x2 mod n2
    ...
    x ~= xk mod nk

    This system of congruences has a single simultaneous solution x
    between 0 and n - 1. Furthermore, each xk solution and x itself
    is congruent modulo the product n = n1*n2*...*nk.
    So x1 mod n = x2 mod n = xk mod n = x mod n.

    The single simultaneous solution x can be solved with the following
    equation:

    x = sum(xi*ri*si) mod n where ri = n/ni and si = ri^-1 mod ni.

    Where x is less than n, xi = x mod ni.

    For RSA we are only concerned with k = 2. The modulus n = pq, where
    p and q are coprime. The RSA decryption algorithm is:

    y = x^d mod n

    Given the above:

    x1 = x^d mod p
    r1 = n/p = q
    s1 = q^-1 mod p
    x2 = x^d mod q
    r2 = n/q = p
    s2 = p^-1 mod q

    So y = (x1r1s1 + x2r2s2) mod n
         = ((x^d mod p)q(q^-1 mod p) + (x^d mod q)p(p^-1 mod q)) mod n

    According to Fermat's Little Theorem, if the modulus P is prime,
    for any integer A not evenly divisible by P, A^(P-1) ~= 1 mod P.
    Since A is not divisible by P it follows that if:
    N ~= M mod (P - 1), then A^N mod P = A^M mod P. Therefore:

    A^N mod P = A^(M mod (P - 1)) mod P. (The latter takes less effort
    to calculate). In order to calculate x^d mod p more quickly the
    exponent d mod (p - 1) is stored in the RSA private key (the same
    is done for x^d mod q). These values are referred to as dP and dQ
    respectively. Therefore we now have:

    y = ((x^dP mod p)q(q^-1 mod p) + (x^dQ mod q)p(p^-1 mod q)) mod n

    Since we'll be reducing x^dP by modulo p (same for q) we can also
    reduce x by p (and q respectively) before hand. Therefore, let

    xp = ((x mod p)^dP mod p), and
    xq = ((x mod q)^dQ mod q), yielding:

    y = (xp*q*(q^-1 mod p) + xq*p*(p^-1 mod q)) mod n

    This can be further reduced to a simple algorithm that only
    requires 1 inverse (the q inverse is used) to be used and stored.
    The algorithm is called Garner's algorithm. If qInv is the
    inverse of q, we simply calculate:

    y = (qInv*(xp - xq) mod p) * q + xq

    However, there are two further complications. First, we need to
    ensure that xp > xq to prevent signed BigIntegers from being used
    so we add p until this is true (since we will be mod'ing with
    p anyway). Then, there is a known timing attack on algorithms
    using the CRT. To mitigate this risk, "cryptographic blinding"
    should be used. This requires simply generating a random number r between
    0 and n-1 and its inverse and multiplying x by r^e before calculating y
    and then multiplying y by r^-1 afterwards.
  */

  // cryptographic blinding
  var r;
  do {
    r = new BigInteger(
      forge.util.bytesToHex(forge.random.getBytes(key.n.bitLength() / 8)),
      16).mod(key.n);
  } while(r.equals(BigInteger.ZERO));
  x = x.multiply(r.modPow(key.e, key.n)).mod(key.n);

  // calculate xp and xq
  var xp = x.mod(key.p).modPow(key.dP, key.p);
  var xq = x.mod(key.q).modPow(key.dQ, key.q);

  // xp must be larger than xq to avoid signed bit usage
  while(xp.compareTo(xq) < 0) {
    xp = xp.add(key.p);
  }

  // do last step
  var y = xp.subtract(xq)
    .multiply(key.qInv).mod(key.p)
    .multiply(key.q).add(xq);

  // remove effect of random for cryptographic blinding
  y = y.multiply(r.modInverse(key.n)).mod(key.n);

  return y;
}
1318376
function RSAGenerate(B,E) {
  var rng = new SecureRandom();
  var qs = B>>1;
  this.e = parseInt(E,16);
  var ee = new BigInteger(E,16);
  for(;;) {
    for(;;) {
      this.p = new BigInteger(B-qs,1,rng);
      if(this.p.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.p.isProbablePrime(10)) break;
    }
    for(;;) {
      this.q = new BigInteger(qs,1,rng);
      if(this.q.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.q.isProbablePrime(10)) break;
    }
    if(this.p.compareTo(this.q) <= 0) {
      var t = this.p;
      this.p = this.q;
      this.q = t;
    }
    var p1 = this.p.subtract(BigInteger.ONE);
    var q1 = this.q.subtract(BigInteger.ONE);
    var phi = p1.multiply(q1);
    if(phi.gcd(ee).compareTo(BigInteger.ONE) == 0) {
      this.n = this.p.multiply(this.q);
      this.d = ee.modInverse(phi);
      this.dmp1 = this.d.mod(p1);
      this.dmq1 = this.d.mod(q1);
      this.coeff = this.q.modInverse(this.p);
      break;
    }
  }
}
1371040
public static void fe_add(int[] h,int[] f,int[] g)
{
  int f0 = f[0];
  int f1 = f[1];
  int f2 = f[2];
  int f3 = f[3];
  int f4 = f[4];
  int f5 = f[5];
  int f6 = f[6];
  int f7 = f[7];
  int f8 = f[8];
  int f9 = f[9];
  int g0 = g[0];
  int g1 = g[1];
  int g2 = g[2];
  int g3 = g[3];
  int g4 = g[4];
  int g5 = g[5];
  int g6 = g[6];
  int g7 = g[7];
  int g8 = g[8];
  int g9 = g[9];
  int h0 = f0 + g0;
  int h1 = f1 + g1;
  int h2 = f2 + g2;
  int h3 = f3 + g3;
  int h4 = f4 + g4;
  int h5 = f5 + g5;
  int h6 = f6 + g6;
  int h7 = f7 + g7;
  int h8 = f8 + g8;
  int h9 = f9 + g9;
  h[0] = (int)h0;
  h[1] = (int)h1;
  h[2] = (int)h2;
  h[3] = (int)h3;
  h[4] = (int)h4;
  h[5] = (int)h5;
  h[6] = (int)h6;
  h[7] = (int)h7;
  h[8] = (int)h8;
  h[9] = (int)h9;
}
1088515
def subtractprivkeys(p1,p2):
    '''
    
    '''

    return dechex(((int(p1,16) + (N - int(p2,16))) % N),32)
306957
function Fe(pt,ut,bt){// Remove trailing zeros.
for(var ht=1,mt=ut.length;!ut[--mt];ut.pop());// Calculate the base 10 exponent. First get the number of digits of c[0].
for(mt=ut[0];10<=mt;mt/=10,ht++);// Overflow?
return(bt=ht+bt*Re-1)>$e?pt.c=pt.e=null:bt<Qe?pt.c=[pt.e=0]:(pt.e=bt,pt.c=ut),pt}
612986
void multiply(DiyFp other) {
        // Simply "emulates" a 128 bit multiplication.
        // However: the resulting number only contains 64 bits. The least
        // significant 64 bits are only used for rounding the most significant 64
        // bits.
        final long kM32 = 0xFFFFFFFFL;
        long a = f >>> 32;
        long b = f & kM32;
        long c = other.f >>> 32;
        long d = other.f & kM32;
        long ac = a * c;
        long bc = b * c;
        long ad = a * d;
        long bd = b * d;
        long tmp = (bd >>> 32) + (ad & kM32) + (bc & kM32);
        // By adding 1U << 31 to tmp we round the final result.
        // Halfway cases will be round up.
        tmp += 1L << 31;
        long result_f = ac + (ad >>> 32) + (bc >>> 32) + (tmp >>> 32);
        e += other.e + 64;
        f = result_f;
    }
621227
def modular_exponential(base, exponent, mod):
    """"""
    if exponent < 0:
        raise ValueError("Exponent must be positive.")
    base %= mod
    result = 1

    while exponent > 0:
        # If the last bit is 1, add 2^k.
        if exponent & 1:
            result = (result * base) % mod
        exponent = exponent >> 1
        # Utilize modular multiplication properties to combine the computed mod C values.
        base = (base * base) % mod

    return result
877740
function pointFpMultiplyTwo(j,x,k) {
  var i;
  if(j.bitLength() > k.bitLength())
    i = j.bitLength() - 1;
  else
    i = k.bitLength() - 1;

  var R = this.curve.getInfinity();
  var both = this.add(x);
  while(i >= 0) {
    R = R.twice();
    if(j.testBit(i)) {
      if(k.testBit(i)) {
        R = R.add(both);
      }
      else {
        R = R.add(this);
      }
    }
    else {
      if(k.testBit(i)) {
        R = R.add(x);
      }
    }
    --i;
  }

  return R;
}