<commit_before>/**
 * \file mcmc_main.cpp: GFA (Graph Alignment Format) Fast Emitter: a new mapper that will be *extremely* fast once we actually write it
 */

#include <omp.h>
#include <unistd.h>
#include <getopt.h>
#include <iostream>
#include <typeinfo>
#include <cassert>
#include <vector>
#include "subcommand.hpp"
#include <vg/io/vpkg.hpp>
#include "../mcmc_genotyper.hpp"
#include "../vg.hpp"
#include "../multipath_alignment.hpp"
#include "../mcmc_caller.hpp"
#include "../graph_caller.hpp"
#include <vg/io/stream.hpp>
#include <bdsg/overlays/overlay_helper.hpp>
#include <fstream>
#include <iostream>

using namespace std;
using namespace vg;
using namespace vg::subcommand;

void help_mcmc(char** argv) {
    cerr
    << "usage: " << argv[0] << " mcmc [options] multipath_alns.mgam graph.vg sites.snarls > graph_with_paths.vg" << endl
    << "Finds haplotypes based on reads using MCMC methods" << endl
    << endl
    << "basic options:" << endl
    << "  -i, --iteration-number INT        tells us the number of iterations to run mcmc_genotyper with" <<endl
    << "  -r, --seed INT                    the seed we will use for the random number generator " << endl
    << "  -s, --sample NAME                 sample name [default=SAMPLE]" << endl
    << "  -p  --ref-path NAME               reference path to call on (multipile allowed.  defaults to all paths)"<< endl
    << "  -o, --ref-offset N                offset in reference path (multiple allowed, 1 per path)" << endl
    << "  -l, --ref-length N                override length of reference in the contig field of output VCF" << endl
    << "  -v, --vcf-out FILE                write VCF output to this file" << endl
    << "  -b, --burn-in INT                 number of iterations to run original sample proposal only" <<endl
    << "  -g, --gamma-freq INT              the frequency (every n iterations) for which to re-make the gamma set (starts after burn-in)" <<endl;
}

int main_mcmc(int argc, char** argv) {

    vector<string> ref_paths;
    vector<size_t> ref_path_offsets;
    vector<size_t> ref_path_lengths;

    string vcf_out;
    int burn_in;
    int gamma_freq;

    if (argc < 7) {
        help_mcmc(argv);
        return 1;
    }

    // initialize parameters with their default options
    int n_iterations = 1000;
    int seed = std::chrono::system_clock::now().time_since_epoch().count();
    string sample_name = "SAMPLE";

    int c;
    optind = 2; // force optind past command positional argument
    while (true) {
        static struct option long_options[] =
        {
            {"help", no_argument, 0, 'h'},
            {"iteration-number", required_argument, 0, 'i'},
            {"seed", required_argument, 0, 'r'},
            {"sample", required_argument, 0, 's'},
            {"ref-path", required_argument, 0, 'p'},
            {"ref-offset", required_argument, 0, 'o'},
            {"ref-length", required_argument, 0, 'l'},
            {"vcf-out", required_argument, 0, 'v'},
            {"burn-in", required_argument, 0, 'b'},
            {"gamma-freq", required_argument, 0, 'g'},
            {0, 0, 0, 0}
        };

        int option_index = 0;
        c = getopt_long (argc, argv, "hi:s:p:o:l:r:v:b:g:",
                         long_options, &option_index);

        // Detect the end of the options.
        if (c == -1)
            break;

        switch (c)
        {
            case 'i':
                n_iterations = parse<int>(optarg);
                break;
            case 'r':
                seed = parse<int>(optarg);
                break;
            case 'p':
                ref_paths.push_back(optarg);
                break;
            case 'o':
                ref_path_offsets.push_back(parse<int>(optarg));
                break;
            case 'l':
                ref_path_lengths.push_back(parse<int>(optarg));
                break;
            case 's':
                sample_name = optarg;
                break;
            case 'v':
                vcf_out = optarg;
                break;
            case 'b':
                burn_in = parse<int>(optarg);
                break;
            case 'g':
                gamma_freq = parse<int>(optarg);
                break;
            case 'h':
            case '?':
            default:
                help_mcmc(argv);
                exit(1);
                break;
        }
    }

    string multipath_file =  get_input_file_name(optind, argc, argv);
    string graph_file =  get_input_file_name(optind, argc, argv);
    string snarls_file =  get_input_file_name(optind, argc, argv);

    unique_ptr<SnarlManager> snarls = (vg::io::VPKG::load_one<SnarlManager>(snarls_file));

    // // create a PathHandleGraph
    unique_ptr<VG> vg_graph;
    bdsg::PathPositionOverlayHelper overlay_helper;
    vg_graph = vg::io::VPKG::load_one<VG>(graph_file);

    if(vg_graph.get() == nullptr || vg_graph.get() == 0){
        cerr << "Graph is NULL" <<endl;
        exit(1);
    }
    PathPositionHandleGraph* graph = nullptr;
    graph = overlay_helper.apply(vg_graph.get());

    // Check our paths
    for (const string& ref_path : ref_paths) {
        if (!graph->has_path(ref_path)) {
            cerr << "error [vg call]: Reference path \"" << ref_path << "\" not found in graph" << endl;
            return 1;
        }
    }

    // Check our offsets
    if (ref_path_offsets.size() != 0 && ref_path_offsets.size() != ref_paths.size()) {
        cerr << "error [vg call]: when using -o, the same number paths must be given with -p" << endl;
        return 1;
    }
    // Check our ref lengths
    if (ref_path_lengths.size() != 0 && ref_path_lengths.size() != ref_paths.size()) {
        cerr << "error [vg call]: when using -l, the same number paths must be given with -p" << endl;
        return 1;
    }

    // No paths specified: use them all
    if (ref_paths.empty()) {
        graph->for_each_path_handle([&](path_handle_t path_handle) {
                const string& name = graph->get_path_name(path_handle);
                if (!Paths::is_alt(name)) {
                    ref_paths.push_back(name);
                }
            });

    }

    // Check if VCF output file is specified
    ofstream vcf_file_out;
    if(!vcf_out.empty()){
        vcf_file_out.open(vcf_out, ios::out);
    }

      /*
    *########################################################################################
    *                      GENOTYPING
    *########################################################################################
    **/

    vector<multipath_alignment_t> reads;
    get_input_file(multipath_file, [&] (istream& open_file){
        io::ProtobufIterator<MultipathAlignment> iter (open_file);
        while(iter.has_current()){
            reads.emplace_back();
            from_proto_multipath_alignment(*iter, reads.back());
            // vg::view_multipath_alignment_as_dot(cerr,*iter,true);
            ++iter;
        }
    });
    double log_base = gssw_dna_recover_log_base(1,4,.5,1e-12);
    // invoke run genotyper
    MCMCGenotyper mcmc_genotyper(*snarls, *vg_graph, n_iterations, seed, burn_in, gamma_freq);
    unique_ptr<PhasedGenome> genome = mcmc_genotyper.run_genotype(reads, log_base);

    // genome->print_phased_genome();

    /*
    *########################################################################################
    *                      VCF OUTPUT
    *########################################################################################
    **/

    // Create MCMC_Caller object
    MCMCCaller mcmc_caller(graph, *genome, *snarls, sample_name, ref_paths, ref_path_offsets, ref_path_lengths, cout);

    // Write header to ofstream
    vcf_file_out << mcmc_caller.vcf_header(*graph, ref_paths, ref_path_lengths);

    //current implimentation is writing vcf record after each variant processed
    mcmc_caller.call_top_level_snarls();

    // mcmc_caller.write_variants(cerr);
    mcmc_caller.write_variants(vcf_file_out);

    //close the vcf file
    vcf_file_out.close();

    // will output a graph w/ embedded paths
    vg_graph->serialize_to_ostream(std::cout);

    return 0;
}

// Register subcommand
static Subcommand vg_mcmc("mcmc", "Finds haplotypes based on reads using MCMC methods", DEVELOPMENT, main_mcmc);

<commit_msg>Add ensure_vg() into mcmc_main subcommand<commit_after>/**
 * \file mcmc_main.cpp: GFA (Graph Alignment Format) Fast Emitter: a new mapper that will be *extremely* fast once we actually write it
 */

#include <omp.h>
#include <unistd.h>
#include <getopt.h>
#include <iostream>
#include <typeinfo>
#include <cassert>
#include <vector>
#include "subcommand.hpp"
#include <vg/io/vpkg.hpp>
#include "../mcmc_genotyper.hpp"
#include "../vg.hpp"
#include "../multipath_alignment.hpp"
#include "../mcmc_caller.hpp"
#include "../graph_caller.hpp"
#include <vg/io/stream.hpp>
#include <bdsg/overlays/overlay_helper.hpp>
#include <fstream>
#include <iostream>

using namespace std;
using namespace vg;
using namespace vg::subcommand;

void help_mcmc(char** argv) {
    cerr
    << "usage: " << argv[0] << " mcmc [options] multipath_alns.mgam graph.vg sites.snarls > graph_with_paths.vg" << endl
    << "Finds haplotypes based on reads using MCMC methods" << endl
    << endl
    << "basic options:" << endl
    << "  -i, --iteration-number INT        tells us the number of iterations to run mcmc_genotyper with" <<endl
    << "  -r, --seed INT                    the seed we will use for the random number generator " << endl
    << "  -s, --sample NAME                 sample name [default=SAMPLE]" << endl
    << "  -p  --ref-path NAME               reference path to call on (multipile allowed.  defaults to all paths)"<< endl
    << "  -o, --ref-offset N                offset in reference path (multiple allowed, 1 per path)" << endl
    << "  -l, --ref-length N                override length of reference in the contig field of output VCF" << endl
    << "  -v, --vcf-out FILE                write VCF output to this file" << endl
    << "  -b, --burn-in INT                 number of iterations to run original sample proposal only" <<endl
    << "  -g, --gamma-freq INT              the frequency (every n iterations) for which to re-make the gamma set (starts after burn-in)" <<endl;
}

int main_mcmc(int argc, char** argv) {

    vector<string> ref_paths;
    vector<size_t> ref_path_offsets;
    vector<size_t> ref_path_lengths;

    string vcf_out;
    int burn_in;
    int gamma_freq;

    if (argc < 7) {
        help_mcmc(argv);
        return 1;
    }

    // initialize parameters with their default options
    int n_iterations = 1000;
    int seed = std::chrono::system_clock::now().time_since_epoch().count();
    string sample_name = "SAMPLE";

    int c;
    optind = 2; // force optind past command positional argument
    while (true) {
        static struct option long_options[] =
        {
            {"help", no_argument, 0, 'h'},
            {"iteration-number", required_argument, 0, 'i'},
            {"seed", required_argument, 0, 'r'},
            {"sample", required_argument, 0, 's'},
            {"ref-path", required_argument, 0, 'p'},
            {"ref-offset", required_argument, 0, 'o'},
            {"ref-length", required_argument, 0, 'l'},
            {"vcf-out", required_argument, 0, 'v'},
            {"burn-in", required_argument, 0, 'b'},
            {"gamma-freq", required_argument, 0, 'g'},
            {0, 0, 0, 0}
        };

        int option_index = 0;
        c = getopt_long (argc, argv, "hi:s:p:o:l:r:v:b:g:",
                         long_options, &option_index);

        // Detect the end of the options.
        if (c == -1)
            break;

        switch (c)
        {
            case 'i':
                n_iterations = parse<int>(optarg);
                break;
            case 'r':
                seed = parse<int>(optarg);
                break;
            case 'p':
                ref_paths.push_back(optarg);
                break;
            case 'o':
                ref_path_offsets.push_back(parse<int>(optarg));
                break;
            case 'l':
                ref_path_lengths.push_back(parse<int>(optarg));
                break;
            case 's':
                sample_name = optarg;
                break;
            case 'v':
                vcf_out = optarg;
                break;
            case 'b':
                burn_in = parse<int>(optarg);
                break;
            case 'g':
                gamma_freq = parse<int>(optarg);
                break;
            case 'h':
            case '?':
            default:
                help_mcmc(argv);
                exit(1);
                break;
        }
    }

    string multipath_file =  get_input_file_name(optind, argc, argv);
    string graph_file =  get_input_file_name(optind, argc, argv);
    string snarls_file =  get_input_file_name(optind, argc, argv);

    unique_ptr<SnarlManager> snarls = (vg::io::VPKG::load_one<SnarlManager>(snarls_file));

    // // create a PathHandleGraph
    unique_ptr<PathHandleGraph> path_hgraph;
    bdsg::PathPositionOverlayHelper overlay_helper;
    path_hgraph = vg::io::VPKG::load_one<PathHandleGraph>(graph_file);

    // Some stuff below here needs a vg graph.
    VG* vg_graph = dynamic_cast<vg::VG*>(path_hgraph.get());

    // Call this to populate the vg_graph if it isn't populated.
    auto ensure_vg = [&]() -> vg::VG* {
        if (vg_graph == nullptr) {
            // Copy instead.
            vg_graph = new vg::VG();
            handlealgs::copy_path_handle_graph(path_hgraph.get(), vg_graph);
            // Give the unique_ptr ownership and delete the graph we loaded.
            path_hgraph.reset(vg_graph);
            // Make sure the paths are all synced up
            vg_graph->paths.to_graph(vg_graph->graph);
        }
        return vg_graph;
    };

    //convert to VG graph if needed
    ensure_vg();

    if(vg_graph == nullptr || vg_graph == 0){
        cerr << "Graph is NULL" <<endl;
        exit(1);
    }
    PathPositionHandleGraph* graph = nullptr;
    graph = overlay_helper.apply(vg_graph);

    // Check our paths
    for (const string& ref_path : ref_paths) {
        if (!graph->has_path(ref_path)) {
            cerr << "error [vg call]: Reference path \"" << ref_path << "\" not found in graph" << endl;
            return 1;
        }
    }

    // Check our offsets
    if (ref_path_offsets.size() != 0 && ref_path_offsets.size() != ref_paths.size()) {
        cerr << "error [vg call]: when using -o, the same number paths must be given with -p" << endl;
        return 1;
    }
    // Check our ref lengths
    if (ref_path_lengths.size() != 0 && ref_path_lengths.size() != ref_paths.size()) {
        cerr << "error [vg call]: when using -l, the same number paths must be given with -p" << endl;
        return 1;
    }

    // No paths specified: use them all
    if (ref_paths.empty()) {
        graph->for_each_path_handle([&](path_handle_t path_handle) {
                const string& name = graph->get_path_name(path_handle);
                if (!Paths::is_alt(name)) {
                    ref_paths.push_back(name);
                }
            });

    }

    // Check if VCF output file is specified
    ofstream vcf_file_out;
    if(!vcf_out.empty()){
        vcf_file_out.open(vcf_out, ios::out);
    }

      /*
    *########################################################################################
    *                      GENOTYPING
    *########################################################################################
    **/

    vector<multipath_alignment_t> reads;
    get_input_file(multipath_file, [&] (istream& open_file){
        io::ProtobufIterator<MultipathAlignment> iter (open_file);
        while(iter.has_current()){
            reads.emplace_back();
            from_proto_multipath_alignment(*iter, reads.back());
            // vg::view_multipath_alignment_as_dot(cerr,*iter,true);
            ++iter;
        }
    });
    double log_base = gssw_dna_recover_log_base(1,4,.5,1e-12);
    // invoke run genotyper
    MCMCGenotyper mcmc_genotyper(*snarls, *vg_graph, n_iterations, seed, burn_in, gamma_freq);
    unique_ptr<PhasedGenome> genome = mcmc_genotyper.run_genotype(reads, log_base);

    // genome->print_phased_genome();

    /*
    *########################################################################################
    *                      VCF OUTPUT
    *########################################################################################
    **/

    // Create MCMC_Caller object
    MCMCCaller mcmc_caller(graph, *genome, *snarls, sample_name, ref_paths, ref_path_offsets, ref_path_lengths, cout);

    // Write header to ofstream
    vcf_file_out << mcmc_caller.vcf_header(*graph, ref_paths, ref_path_lengths);

    //current implimentation is writing vcf record after each variant processed
    mcmc_caller.call_top_level_snarls();

    // mcmc_caller.write_variants(cerr);
    mcmc_caller.write_variants(vcf_file_out);

    //close the vcf file
    vcf_file_out.close();

    // will output a graph w/ embedded paths
    vg_graph->serialize_to_ostream(std::cout);

    return 0;
}

// Register subcommand
static Subcommand vg_mcmc("mcmc", "Finds haplotypes based on reads using MCMC methods", DEVELOPMENT, main_mcmc);

<|endoftext|>


<commit_before><commit_msg>MGenTest: Show urlencoded<commit_after><|endoftext|>


<commit_before>/*
* Number Theory Functions
* (C) 1999-2011,2016,2018,2019 Jack Lloyd
* (C) 2007,2008 Falko Strenzke, FlexSecure GmbH
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/numthry.h>
#include <botan/reducer.h>
#include <botan/internal/monty.h>
#include <botan/internal/divide.h>
#include <botan/rng.h>
#include <botan/internal/ct_utils.h>
#include <botan/internal/mp_core.h>
#include <botan/internal/monty_exp.h>
#include <botan/internal/primality.h>
#include <algorithm>

namespace Botan {

namespace {

void sub_abs(BigInt& z, const BigInt& x, const BigInt& y)
   {
   const size_t x_sw = x.sig_words();
   const size_t y_sw = y.sig_words();
   z.resize(std::max(x_sw, y_sw));

   bigint_sub_abs(z.mutable_data(),
                  x.data(), x_sw,
                  y.data(), y_sw);
   }

}

/*
* Tonelli-Shanks algorithm
*/
BigInt ressol(const BigInt& a, const BigInt& p)
   {
   if(p <= 1 || p.is_even())
      throw Invalid_Argument("ressol: invalid prime");

   if(a == 0)
      return 0;
   else if(a < 0)
      throw Invalid_Argument("ressol: value to solve for must be positive");
   else if(a >= p)
      throw Invalid_Argument("ressol: value to solve for must be less than p");

   if(p == 2)
      return a;

   if(jacobi(a, p) != 1) // not a quadratic residue
      return -BigInt(1);

   Modular_Reducer mod_p(p);
   auto monty_p = std::make_shared<Montgomery_Params>(p, mod_p);

   if(p % 4 == 3) // The easy case
      {
      return monty_exp_vartime(monty_p, a, ((p+1) >> 2));
      }

   size_t s = low_zero_bits(p - 1);
   BigInt q = p >> s;

   q -= 1;
   q >>= 1;

   BigInt r = monty_exp_vartime(monty_p, a, q);
   BigInt n = mod_p.multiply(a, mod_p.square(r));
   r = mod_p.multiply(r, a);

   if(n == 1)
      return r;

   // find random quadratic nonresidue z
   word z = 2;
   for(;;)
      {
      if(jacobi(z, p) == -1) // found one
         break;

      z += 1; // try next z

      /*
      * The expected number of tests to find a non-residue modulo a
      * prime is 2. If we have not found one after 256 then almost
      * certainly we have been given a non-prime p.
      */
      if(z >= 256)
         return -BigInt(1);
      }

   BigInt c = monty_exp_vartime(monty_p, z, (q << 1) + 1);

   while(n > 1)
      {
      q = n;

      size_t i = 0;
      while(q != 1)
         {
         q = mod_p.square(q);
         ++i;

         if(i >= s)
            {
            return -BigInt(1);
            }
         }

      c = monty_exp_vartime(monty_p, c, BigInt::power_of_2(s-i-1));
      r = mod_p.multiply(r, c);
      c = mod_p.square(c);
      n = mod_p.multiply(n, c);
      s = i;
      }

   return r;
   }

/*
* Calculate the Jacobi symbol
*/
int32_t jacobi(const BigInt& a, const BigInt& n)
   {
   if(n.is_even() || n < 2)
      throw Invalid_Argument("jacobi: second argument must be odd and > 1");

   BigInt x = a % n;
   BigInt y = n;
   int32_t J = 1;

   while(y > 1)
      {
      x %= y;
      if(x > y / 2)
         {
         x = y - x;
         if(y % 4 == 3)
            J = -J;
         }
      if(x.is_zero())
         return 0;

      size_t shifts = low_zero_bits(x);
      x >>= shifts;
      if(shifts % 2)
         {
         word y_mod_8 = y % 8;
         if(y_mod_8 == 3 || y_mod_8 == 5)
            J = -J;
         }

      if(x % 4 == 3 && y % 4 == 3)
         J = -J;
      std::swap(x, y);
      }
   return J;
   }

/*
* Square a BigInt
*/
BigInt square(const BigInt& x)
   {
   BigInt z = x;
   secure_vector<word> ws;
   z.square(ws);
   return z;
   }

/*
* Return the number of 0 bits at the end of n
*/
size_t low_zero_bits(const BigInt& n)
   {
   size_t low_zero = 0;

   auto seen_nonempty_word = CT::Mask<word>::cleared();

   for(size_t i = 0; i != n.size(); ++i)
      {
      const word x = n.word_at(i);

      // ctz(0) will return sizeof(word)
      const size_t tz_x = ctz(x);

      // if x > 0 we want to count tz_x in total but not any
      // further words, so set the mask after the addition
      low_zero += seen_nonempty_word.if_not_set_return(tz_x);

      seen_nonempty_word |= CT::Mask<word>::expand(x);
      }

   // if we saw no words with x > 0 then n == 0 and the value we have
   // computed is meaningless. Instead return 0 in that case.
   return seen_nonempty_word.if_set_return(low_zero);
   }

/*
* Calculate the GCD
*/
BigInt gcd(const BigInt& a, const BigInt& b)
   {
   if(a.is_zero() || b.is_zero())
      return 0;
   if(a == 1 || b == 1)
      return 1;

   // See https://gcd.cr.yp.to/safegcd-20190413.pdf fig 1.2

   BigInt f = a;
   BigInt g = b;
   f.const_time_poison();
   g.const_time_poison();

   f.set_sign(BigInt::Positive);
   g.set_sign(BigInt::Positive);

   const size_t common2s = std::min(low_zero_bits(f), low_zero_bits(g));
   CT::unpoison(common2s);

   f >>= common2s;
   g >>= common2s;

   f.ct_cond_swap(f.is_even(), g);

   int32_t delta = 1;

   const size_t loop_cnt = 4 + 3*std::max(f.bits(), g.bits());

   BigInt newg, t;
   for(size_t i = 0; i != loop_cnt; ++i)
      {
      sub_abs(newg, f, g);

      const bool need_swap = (g.is_odd() && delta > 0);

      // if(need_swap) delta *= -1
      delta *= CT::Mask<uint8_t>::expand(need_swap).select(0, 2) - 1;
      f.ct_cond_swap(need_swap, g);
      g.ct_cond_swap(need_swap, newg);

      delta += 1;

      g.ct_cond_add(g.is_odd(), f);
      g >>= 1;
      }

   f <<= common2s;

   f.const_time_unpoison();
   g.const_time_unpoison();

   return f;
   }

/*
* Calculate the LCM
*/
BigInt lcm(const BigInt& a, const BigInt& b)
   {
   return ct_divide(a * b, gcd(a, b));
   }

/*
* Modular Exponentiation
*/
BigInt power_mod(const BigInt& base, const BigInt& exp, const BigInt& mod)
   {
   if(mod.is_negative() || mod == 1)
      {
      return 0;
      }

   if(base.is_zero() || mod.is_zero())
      {
      if(exp.is_zero())
         return 1;
      return 0;
      }

   Modular_Reducer reduce_mod(mod);

   const size_t exp_bits = exp.bits();

   if(mod.is_odd())
      {
      auto monty_params = std::make_shared<Montgomery_Params>(mod, reduce_mod);
      return monty_exp(monty_params, reduce_mod.reduce(base), exp, exp_bits);
      }

   /*
   Support for even modulus is just a convenience and not considered
   cryptographically important, so this implementation is slow ...
   */
   BigInt accum = 1;
   BigInt g = reduce_mod.reduce(base);
   BigInt t;

   for(size_t i = 0; i != exp_bits; ++i)
      {
      t = reduce_mod.multiply(g, accum);
      g = reduce_mod.square(g);
      accum.ct_cond_assign(exp.get_bit(i), t);
      }
   return accum;
   }

BigInt is_perfect_square(const BigInt& C)
   {
   if(C < 1)
      throw Invalid_Argument("is_perfect_square requires C >= 1");
   if(C == 1)
      return 1;

   const size_t n = C.bits();
   const size_t m = (n + 1) / 2;
   const BigInt B = C + BigInt::power_of_2(m);

   BigInt X = BigInt::power_of_2(m) - 1;
   BigInt X2 = (X*X);

   for(;;)
      {
      X = (X2 + C) / (2*X);
      X2 = (X*X);

      if(X2 < B)
         break;
      }

   if(X2 == C)
      return X;
   else
      return 0;
   }

/*
* Test for primality using Miller-Rabin
*/
bool is_prime(const BigInt& n,
              RandomNumberGenerator& rng,
              size_t prob,
              bool is_random)
   {
   if(n == 2)
      return true;
   if(n <= 1 || n.is_even())
      return false;

   const size_t n_bits = n.bits();

   // Fast path testing for small numbers (<= 65521)
   if(n_bits <= 16)
      {
      const uint16_t num = static_cast<uint16_t>(n.word_at(0));

      return std::binary_search(PRIMES, PRIMES + PRIME_TABLE_SIZE, num);
      }

   Modular_Reducer mod_n(n);

   if(rng.is_seeded())
      {
      const size_t t = miller_rabin_test_iterations(n_bits, prob, is_random);

      if(is_miller_rabin_probable_prime(n, mod_n, rng, t) == false)
         return false;

      if(is_random)
         return true;
      else
         return is_lucas_probable_prime(n, mod_n);
      }
   else
      {
      return is_bailie_psw_probable_prime(n, mod_n);
      }
   }

}
<commit_msg>Encapsulate safegcd iterations<commit_after>/*
* Number Theory Functions
* (C) 1999-2011,2016,2018,2019 Jack Lloyd
* (C) 2007,2008 Falko Strenzke, FlexSecure GmbH
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/numthry.h>
#include <botan/reducer.h>
#include <botan/internal/monty.h>
#include <botan/internal/divide.h>
#include <botan/rng.h>
#include <botan/internal/ct_utils.h>
#include <botan/internal/mp_core.h>
#include <botan/internal/monty_exp.h>
#include <botan/internal/primality.h>
#include <algorithm>

namespace Botan {

namespace {

void sub_abs(BigInt& z, const BigInt& x, const BigInt& y)
   {
   const size_t x_sw = x.sig_words();
   const size_t y_sw = y.sig_words();
   z.resize(std::max(x_sw, y_sw));

   bigint_sub_abs(z.mutable_data(),
                  x.data(), x_sw,
                  y.data(), y_sw);
   }

}

/*
* Tonelli-Shanks algorithm
*/
BigInt ressol(const BigInt& a, const BigInt& p)
   {
   if(p <= 1 || p.is_even())
      throw Invalid_Argument("ressol: invalid prime");

   if(a == 0)
      return 0;
   else if(a < 0)
      throw Invalid_Argument("ressol: value to solve for must be positive");
   else if(a >= p)
      throw Invalid_Argument("ressol: value to solve for must be less than p");

   if(p == 2)
      return a;

   if(jacobi(a, p) != 1) // not a quadratic residue
      return -BigInt(1);

   Modular_Reducer mod_p(p);
   auto monty_p = std::make_shared<Montgomery_Params>(p, mod_p);

   if(p % 4 == 3) // The easy case
      {
      return monty_exp_vartime(monty_p, a, ((p+1) >> 2));
      }

   size_t s = low_zero_bits(p - 1);
   BigInt q = p >> s;

   q -= 1;
   q >>= 1;

   BigInt r = monty_exp_vartime(monty_p, a, q);
   BigInt n = mod_p.multiply(a, mod_p.square(r));
   r = mod_p.multiply(r, a);

   if(n == 1)
      return r;

   // find random quadratic nonresidue z
   word z = 2;
   for(;;)
      {
      if(jacobi(z, p) == -1) // found one
         break;

      z += 1; // try next z

      /*
      * The expected number of tests to find a non-residue modulo a
      * prime is 2. If we have not found one after 256 then almost
      * certainly we have been given a non-prime p.
      */
      if(z >= 256)
         return -BigInt(1);
      }

   BigInt c = monty_exp_vartime(monty_p, z, (q << 1) + 1);

   while(n > 1)
      {
      q = n;

      size_t i = 0;
      while(q != 1)
         {
         q = mod_p.square(q);
         ++i;

         if(i >= s)
            {
            return -BigInt(1);
            }
         }

      c = monty_exp_vartime(monty_p, c, BigInt::power_of_2(s-i-1));
      r = mod_p.multiply(r, c);
      c = mod_p.square(c);
      n = mod_p.multiply(n, c);
      s = i;
      }

   return r;
   }

/*
* Calculate the Jacobi symbol
*/
int32_t jacobi(const BigInt& a, const BigInt& n)
   {
   if(n.is_even() || n < 2)
      throw Invalid_Argument("jacobi: second argument must be odd and > 1");

   BigInt x = a % n;
   BigInt y = n;
   int32_t J = 1;

   while(y > 1)
      {
      x %= y;
      if(x > y / 2)
         {
         x = y - x;
         if(y % 4 == 3)
            J = -J;
         }
      if(x.is_zero())
         return 0;

      size_t shifts = low_zero_bits(x);
      x >>= shifts;
      if(shifts % 2)
         {
         word y_mod_8 = y % 8;
         if(y_mod_8 == 3 || y_mod_8 == 5)
            J = -J;
         }

      if(x % 4 == 3 && y % 4 == 3)
         J = -J;
      std::swap(x, y);
      }
   return J;
   }

/*
* Square a BigInt
*/
BigInt square(const BigInt& x)
   {
   BigInt z = x;
   secure_vector<word> ws;
   z.square(ws);
   return z;
   }

/*
* Return the number of 0 bits at the end of n
*/
size_t low_zero_bits(const BigInt& n)
   {
   size_t low_zero = 0;

   auto seen_nonempty_word = CT::Mask<word>::cleared();

   for(size_t i = 0; i != n.size(); ++i)
      {
      const word x = n.word_at(i);

      // ctz(0) will return sizeof(word)
      const size_t tz_x = ctz(x);

      // if x > 0 we want to count tz_x in total but not any
      // further words, so set the mask after the addition
      low_zero += seen_nonempty_word.if_not_set_return(tz_x);

      seen_nonempty_word |= CT::Mask<word>::expand(x);
      }

   // if we saw no words with x > 0 then n == 0 and the value we have
   // computed is meaningless. Instead return 0 in that case.
   return seen_nonempty_word.if_set_return(low_zero);
   }

namespace {

size_t safegcd_loop_bound(size_t f_bits, size_t g_bits)
   {
   return 4 + 3*std::max(f_bits, g_bits);
   }

}

/*
* Calculate the GCD
*/
BigInt gcd(const BigInt& a, const BigInt& b)
   {
   if(a.is_zero() || b.is_zero())
      return 0;
   if(a == 1 || b == 1)
      return 1;

   // See https://gcd.cr.yp.to/safegcd-20190413.pdf fig 1.2

   BigInt f = a;
   BigInt g = b;
   f.const_time_poison();
   g.const_time_poison();

   f.set_sign(BigInt::Positive);
   g.set_sign(BigInt::Positive);

   const size_t common2s = std::min(low_zero_bits(f), low_zero_bits(g));
   CT::unpoison(common2s);

   f >>= common2s;
   g >>= common2s;

   f.ct_cond_swap(f.is_even(), g);

   int32_t delta = 1;

   const size_t loop_cnt = safegcd_loop_bound(f.bits(), g.bits());

   BigInt newg, t;
   for(size_t i = 0; i != loop_cnt; ++i)
      {
      sub_abs(newg, f, g);

      const bool need_swap = (g.is_odd() && delta > 0);

      // if(need_swap) delta *= -1
      delta *= CT::Mask<uint8_t>::expand(need_swap).select(0, 2) - 1;
      f.ct_cond_swap(need_swap, g);
      g.ct_cond_swap(need_swap, newg);

      delta += 1;

      g.ct_cond_add(g.is_odd(), f);
      g >>= 1;
      }

   f <<= common2s;

   f.const_time_unpoison();
   g.const_time_unpoison();

   return f;
   }

/*
* Calculate the LCM
*/
BigInt lcm(const BigInt& a, const BigInt& b)
   {
   return ct_divide(a * b, gcd(a, b));
   }

/*
* Modular Exponentiation
*/
BigInt power_mod(const BigInt& base, const BigInt& exp, const BigInt& mod)
   {
   if(mod.is_negative() || mod == 1)
      {
      return 0;
      }

   if(base.is_zero() || mod.is_zero())
      {
      if(exp.is_zero())
         return 1;
      return 0;
      }

   Modular_Reducer reduce_mod(mod);

   const size_t exp_bits = exp.bits();

   if(mod.is_odd())
      {
      auto monty_params = std::make_shared<Montgomery_Params>(mod, reduce_mod);
      return monty_exp(monty_params, reduce_mod.reduce(base), exp, exp_bits);
      }

   /*
   Support for even modulus is just a convenience and not considered
   cryptographically important, so this implementation is slow ...
   */
   BigInt accum = 1;
   BigInt g = reduce_mod.reduce(base);
   BigInt t;

   for(size_t i = 0; i != exp_bits; ++i)
      {
      t = reduce_mod.multiply(g, accum);
      g = reduce_mod.square(g);
      accum.ct_cond_assign(exp.get_bit(i), t);
      }
   return accum;
   }

BigInt is_perfect_square(const BigInt& C)
   {
   if(C < 1)
      throw Invalid_Argument("is_perfect_square requires C >= 1");
   if(C == 1)
      return 1;

   const size_t n = C.bits();
   const size_t m = (n + 1) / 2;
   const BigInt B = C + BigInt::power_of_2(m);

   BigInt X = BigInt::power_of_2(m) - 1;
   BigInt X2 = (X*X);

   for(;;)
      {
      X = (X2 + C) / (2*X);
      X2 = (X*X);

      if(X2 < B)
         break;
      }

   if(X2 == C)
      return X;
   else
      return 0;
   }

/*
* Test for primality using Miller-Rabin
*/
bool is_prime(const BigInt& n,
              RandomNumberGenerator& rng,
              size_t prob,
              bool is_random)
   {
   if(n == 2)
      return true;
   if(n <= 1 || n.is_even())
      return false;

   const size_t n_bits = n.bits();

   // Fast path testing for small numbers (<= 65521)
   if(n_bits <= 16)
      {
      const uint16_t num = static_cast<uint16_t>(n.word_at(0));

      return std::binary_search(PRIMES, PRIMES + PRIME_TABLE_SIZE, num);
      }

   Modular_Reducer mod_n(n);

   if(rng.is_seeded())
      {
      const size_t t = miller_rabin_test_iterations(n_bits, prob, is_random);

      if(is_miller_rabin_probable_prime(n, mod_n, rng, t) == false)
         return false;

      if(is_random)
         return true;
      else
         return is_lucas_probable_prime(n, mod_n);
      }
   else
      {
      return is_bailie_psw_probable_prime(n, mod_n);
      }
   }

}
<|endoftext|>


<commit_before><commit_msg>:star: Vertical sum<commit_after><|endoftext|>


<commit_before>#pragma once

#include <deque>
#include <memory>
#include <iostream>
#include <map>
#include <utility>

template <typename T>
class MessageBusProxy;

namespace {
	using Cursor = long unsigned int;

}

template <typename MessageType>
class MessageBus {
	public:

		MessageBus()=default;

		void push(const MessageType& message);

		static MessageBus<MessageType>* getBus();

		MessageType* next(MessageBusProxy<MessageType>* proxy);

	private:
		using MessageQueue = std::deque<MessageType>;
		friend class MessageBusProxy<MessageType>;

		void registerProxy(MessageBusProxy<MessageType>* proxy);
		void unregisterProxy(MessageBusProxy<MessageType>* proxy);

		MessageQueue m_messages;
		std::map<MessageBusProxy<MessageType>*, typename MessageQueue::iterator> m_proxys;

		static std::unique_ptr<MessageBus<MessageType>> m_bus;
};

#include "messagebusqueue.hpp"
#include "messagebusproxy.hpp"

template <typename MessageType>
void MessageBus<MessageType>::push(const MessageType& message)
{
	if (m_proxys.size() == 0)
		return;
	MessageBusQueue::instance()->push<MessageType>();
	m_messages.push_back(message);
}

template <typename MessageType>
MessageBus<MessageType>* MessageBus<MessageType>::getBus()
{
	if (m_bus == nullptr)
	{
		std::cout << "bus expired"<< std::endl;
		m_bus.reset(new MessageBus<MessageType>());
	}
	return m_bus.get();
}

template <typename MessageType>
void MessageBus<MessageType>::registerProxy(MessageBusProxy<MessageType>* proxy) {
	auto cursor = m_messages.begin();
	if (m_messages.size() > 0)
		std::advance(cursor, m_messages.size()-1);
	m_proxys.emplace(proxy, cursor);
}

template <typename MessageType>
void MessageBus<MessageType>::unregisterProxy(MessageBusProxy<MessageType>* proxy) {
	auto _search = m_proxys.find(proxy);
	if (_search == m_proxys.end())
		return;
	m_proxys.erase(_search);

	if (m_proxys.size() == 0)
		delete m_bus.release();
}

template <typename MessageType>
MessageType* MessageBus<MessageType>::next(MessageBusProxy<MessageType>* proxy) {
	// TODO : implement next function
	auto& iterator = m_proxys.at(proxy);
	if (iterator == m_messages.end())
		return nullptr;
	return &*(++iterator);
}

template <typename MessageType>
std::unique_ptr<MessageBus<MessageType>> MessageBus<MessageType>::m_bus = nullptr;
<commit_msg>Add send message shortcut.<commit_after>#pragma once

#include <deque>
#include <memory>
#include <iostream>
#include <map>
#include <utility>

template <typename T>
class MessageBusProxy;

namespace {
	using Cursor = long unsigned int;

}

template <typename MessageType>
class MessageBus {
	public:

		MessageBus()=default;

		void push(const MessageType& message);

		static MessageBus<MessageType>* getBus();

		MessageType* next(MessageBusProxy<MessageType>* proxy);

	private:
		using MessageQueue = std::deque<MessageType>;
		friend class MessageBusProxy<MessageType>;

		void registerProxy(MessageBusProxy<MessageType>* proxy);
		void unregisterProxy(MessageBusProxy<MessageType>* proxy);

		MessageQueue m_messages;
		std::map<MessageBusProxy<MessageType>*, typename MessageQueue::iterator> m_proxys;

		static std::unique_ptr<MessageBus<MessageType>> m_bus;
};

#include "messagebusqueue.hpp"
#include "messagebusproxy.hpp"

template <typename MessageType>
void MessageBus<MessageType>::push(const MessageType& message)
{
	if (m_proxys.size() == 0)
		return;
	MessageBusQueue::instance()->push<MessageType>();
	m_messages.push_back(message);
}

template <typename MessageType>
MessageBus<MessageType>* MessageBus<MessageType>::getBus()
{
	if (m_bus == nullptr)
	{
		std::cout << "bus expired"<< std::endl;
		m_bus.reset(new MessageBus<MessageType>());
	}
	return m_bus.get();
}

template <typename MessageType>
void MessageBus<MessageType>::registerProxy(MessageBusProxy<MessageType>* proxy) {
	auto cursor = m_messages.begin();
	if (m_messages.size() > 0)
		std::advance(cursor, m_messages.size()-1);
	m_proxys.emplace(proxy, cursor);
}

template <typename MessageType>
void MessageBus<MessageType>::unregisterProxy(MessageBusProxy<MessageType>* proxy) {
	auto _search = m_proxys.find(proxy);
	if (_search == m_proxys.end())
		return;
	m_proxys.erase(_search);

	if (m_proxys.size() == 0)
		delete m_bus.release();
}

template <typename MessageType>
MessageType* MessageBus<MessageType>::next(MessageBusProxy<MessageType>* proxy) {
	// TODO : implement next function
	auto& iterator = m_proxys.at(proxy);
	if (iterator == m_messages.end())
		return nullptr;
	return &*(++iterator);
}

template <typename MessageType>
std::unique_ptr<MessageBus<MessageType>> MessageBus<MessageType>::m_bus = nullptr;

template <typename MessageType>
void SendMessage(const MessageType& message) {
	MessageBus<MessageType>::getBus()->push(message);
}
<|endoftext|>


<commit_before>/*
* Elliptic curves over GF(p) Montgomery Representation
* (C) 2014,2015 Jack Lloyd
*     2016 Matthias Gierlings
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/curve_gfp.h>
#include <botan/curve_nistp.h>
#include <botan/numthry.h>
#include <botan/internal/mp_core.h>
#include <botan/internal/mp_asmi.h>

namespace Botan {

namespace {

class CurveGFp_Montgomery final : public CurveGFp_Repr
   {
   public:
      CurveGFp_Montgomery(const BigInt& p, const BigInt& a, const BigInt& b) :
         m_p(p), m_a(a), m_b(b),
         m_p_words(m_p.sig_words()),
         m_p_dash(monty_inverse(m_p.word_at(0)))
         {
         const BigInt r = BigInt::power_of_2(m_p_words * BOTAN_MP_WORD_BITS);

         m_r2  = (r * r) % p;
         m_a_r = (m_a * r) % p;
         m_b_r = (m_b * r) % p;
         }

      const BigInt& get_a() const override { return m_a; }

      const BigInt& get_b() const override { return m_b; }

      const BigInt& get_p() const override { return m_p; }

      const BigInt& get_a_rep() const override { return m_a_r; }

      const BigInt& get_b_rep() const override { return m_b_r; }

      size_t get_p_words() const override { return m_p_words; }

      void to_curve_rep(BigInt& x, secure_vector<word>& ws) const override;

      void from_curve_rep(BigInt& x, secure_vector<word>& ws) const override;

      void curve_mul(BigInt& z, const BigInt& x, const BigInt& y,
                     secure_vector<word>& ws) const override;

      void curve_sqr(BigInt& z, const BigInt& x,
                     secure_vector<word>& ws) const override;
   private:
      BigInt m_p, m_a, m_b;
      size_t m_p_words; // cache of m_p.sig_words()

      // Montgomery parameters
      BigInt m_r2, m_a_r, m_b_r;
      word m_p_dash;
   };

void CurveGFp_Montgomery::to_curve_rep(BigInt& x, secure_vector<word>& ws) const
   {
   const BigInt tx = x;
   curve_mul(x, tx, m_r2, ws);
   }

void CurveGFp_Montgomery::from_curve_rep(BigInt& x, secure_vector<word>& ws) const
   {
   const BigInt tx = x;
   curve_mul(x, tx, 1, ws);
   }

void CurveGFp_Montgomery::curve_mul(BigInt& z, const BigInt& x, const BigInt& y,
                                    secure_vector<word>& ws) const
   {
   if(x.is_zero() || y.is_zero())
      {
      z = 0;
      return;
      }

   const size_t output_size = 2*m_p_words + 1;
   ws.resize(2*(m_p_words+2));

   if(z.size() < output_size)
      z.grow_to(output_size);
   z.clear();

   bigint_monty_mul(z, x, y,
                    m_p.data(), m_p_words, m_p_dash,
                    ws.data(), ws.size());
   }

void CurveGFp_Montgomery::curve_sqr(BigInt& z, const BigInt& x,
                                    secure_vector<word>& ws) const
   {
   if(x.is_zero())
      {
      z = 0;
      return;
      }

   const size_t x_sw = x.sig_words();
   BOTAN_ASSERT(x_sw <= m_p_words, "Input in range");

   const size_t output_size = 2*m_p_words + 1;

   ws.resize(2*(m_p_words+2));

   if(z.size() < output_size)
      z.grow_to(output_size);
   z.clear();

   bigint_monty_sqr(z, x, m_p.data(), m_p_words, m_p_dash,
                    ws.data(), ws.size());
   }

class CurveGFp_NIST : public CurveGFp_Repr
   {
   public:
      CurveGFp_NIST(size_t p_bits, const BigInt& a, const BigInt& b) :
         m_a(a), m_b(b), m_p_words((p_bits + BOTAN_MP_WORD_BITS - 1) / BOTAN_MP_WORD_BITS)
         {
         }

      const BigInt& get_a() const override { return m_a; }

      const BigInt& get_b() const override { return m_b; }

      size_t get_p_words() const override { return m_p_words; }

      const BigInt& get_a_rep() const override { return m_a; }

      const BigInt& get_b_rep() const override { return m_b; }

      void to_curve_rep(BigInt& x, secure_vector<word>& ws) const override
         { redc(x, ws); }

      void from_curve_rep(BigInt& x, secure_vector<word>& ws) const override
         { redc(x, ws); }

      void curve_mul(BigInt& z, const BigInt& x, const BigInt& y,
                     secure_vector<word>& ws) const override;

      void curve_sqr(BigInt& z, const BigInt& x,
                     secure_vector<word>& ws) const override;
   private:
      virtual void redc(BigInt& x, secure_vector<word>& ws) const = 0;

      // Curve parameters
      BigInt m_a, m_b;
      size_t m_p_words; // cache of m_p.sig_words()
   };

void CurveGFp_NIST::curve_mul(BigInt& z, const BigInt& x, const BigInt& y,
                              secure_vector<word>& ws) const
   {
   if(x.is_zero() || y.is_zero())
      {
      z = 0;
      return;
      }

   const size_t p_words = get_p_words();
   const size_t output_size = 2*p_words + 1;

   ws.resize(2*(p_words+2));

   if(z.size() < output_size)
      z.grow_to(output_size);
   z.clear();

   bigint_mul(z, x, y, ws.data(), ws.size());

   this->redc(z, ws);
   }

void CurveGFp_NIST::curve_sqr(BigInt& z, const BigInt& x,
                              secure_vector<word>& ws) const
   {
   if(x.is_zero())
      {
      z = 0;
      return;
      }

   const size_t p_words = get_p_words();
   const size_t output_size = 2*p_words + 1;

   ws.resize(2*(p_words+2));

   if(z.size() < output_size)
      z.grow_to(output_size);
   z.clear();

   bigint_sqr(z.mutable_data(), output_size,
              x.data(), x.size(), x.sig_words(),
              ws.data(), ws.size());

   this->redc(z, ws);
   }

#if defined(BOTAN_HAS_NIST_PRIME_REDUCERS_W32)

/**
* The NIST P-192 curve
*/
class CurveGFp_P192 final : public CurveGFp_NIST
   {
   public:
      CurveGFp_P192(const BigInt& a, const BigInt& b) : CurveGFp_NIST(192, a, b) {}
      const BigInt& get_p() const override { return prime_p192(); }
   private:
      void redc(BigInt& x, secure_vector<word>& ws) const override { redc_p192(x, ws); }
   };

/**
* The NIST P-224 curve
*/
class CurveGFp_P224 final : public CurveGFp_NIST
   {
   public:
      CurveGFp_P224(const BigInt& a, const BigInt& b) : CurveGFp_NIST(224, a, b) {}
      const BigInt& get_p() const override { return prime_p224(); }
   private:
      void redc(BigInt& x, secure_vector<word>& ws) const override { redc_p224(x, ws); }
   };

/**
* The NIST P-256 curve
*/
class CurveGFp_P256 final : public CurveGFp_NIST
   {
   public:
      CurveGFp_P256(const BigInt& a, const BigInt& b) : CurveGFp_NIST(256, a, b) {}
      const BigInt& get_p() const override { return prime_p256(); }
   private:
      void redc(BigInt& x, secure_vector<word>& ws) const override { redc_p256(x, ws); }
   };

/**
* The NIST P-384 curve
*/
class CurveGFp_P384 final : public CurveGFp_NIST
   {
   public:
      CurveGFp_P384(const BigInt& a, const BigInt& b) : CurveGFp_NIST(384, a, b) {}
      const BigInt& get_p() const override { return prime_p384(); }
   private:
      void redc(BigInt& x, secure_vector<word>& ws) const override { redc_p384(x, ws); }
   };

#endif

/**
* The NIST P-521 curve
*/
class CurveGFp_P521 final : public CurveGFp_NIST
   {
   public:
      CurveGFp_P521(const BigInt& a, const BigInt& b) : CurveGFp_NIST(521, a, b) {}
      const BigInt& get_p() const override { return prime_p521(); }
   private:
      void redc(BigInt& x, secure_vector<word>& ws) const override { redc_p521(x, ws); }
   };

}

std::shared_ptr<CurveGFp_Repr>
CurveGFp::choose_repr(const BigInt& p, const BigInt& a, const BigInt& b)
   {
#if defined(BOTAN_HAS_NIST_PRIME_REDUCERS_W32)
   if(p == prime_p192())
      return std::shared_ptr<CurveGFp_Repr>(new CurveGFp_P192(a, b));
   if(p == prime_p224())
      return std::shared_ptr<CurveGFp_Repr>(new CurveGFp_P224(a, b));
   if(p == prime_p256())
      return std::shared_ptr<CurveGFp_Repr>(new CurveGFp_P256(a, b));
   if(p == prime_p384())
      return std::shared_ptr<CurveGFp_Repr>(new CurveGFp_P384(a, b));
#endif

   if(p == prime_p521())
      return std::shared_ptr<CurveGFp_Repr>(new CurveGFp_P521(a, b));

   return std::shared_ptr<CurveGFp_Repr>(new CurveGFp_Montgomery(p, a, b));
   }

}
<commit_msg>Fix overflow in monty_redc<commit_after>/*
* Elliptic curves over GF(p) Montgomery Representation
* (C) 2014,2015 Jack Lloyd
*     2016 Matthias Gierlings
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/curve_gfp.h>
#include <botan/curve_nistp.h>
#include <botan/numthry.h>
#include <botan/internal/mp_core.h>
#include <botan/internal/mp_asmi.h>

namespace Botan {

namespace {

class CurveGFp_Montgomery final : public CurveGFp_Repr
   {
   public:
      CurveGFp_Montgomery(const BigInt& p, const BigInt& a, const BigInt& b) :
         m_p(p), m_a(a), m_b(b),
         m_p_words(m_p.sig_words()),
         m_p_dash(monty_inverse(m_p.word_at(0)))
         {
         const BigInt r = BigInt::power_of_2(m_p_words * BOTAN_MP_WORD_BITS);

         m_r2  = (r * r) % p;
         m_a_r = (m_a * r) % p;
         m_b_r = (m_b * r) % p;
         }

      const BigInt& get_a() const override { return m_a; }

      const BigInt& get_b() const override { return m_b; }

      const BigInt& get_p() const override { return m_p; }

      const BigInt& get_a_rep() const override { return m_a_r; }

      const BigInt& get_b_rep() const override { return m_b_r; }

      size_t get_p_words() const override { return m_p_words; }

      void to_curve_rep(BigInt& x, secure_vector<word>& ws) const override;

      void from_curve_rep(BigInt& x, secure_vector<word>& ws) const override;

      void curve_mul(BigInt& z, const BigInt& x, const BigInt& y,
                     secure_vector<word>& ws) const override;

      void curve_sqr(BigInt& z, const BigInt& x,
                     secure_vector<word>& ws) const override;
   private:
      BigInt m_p, m_a, m_b;
      size_t m_p_words; // cache of m_p.sig_words()

      // Montgomery parameters
      BigInt m_r2, m_a_r, m_b_r;
      word m_p_dash;
   };

void CurveGFp_Montgomery::to_curve_rep(BigInt& x, secure_vector<word>& ws) const
   {
   const BigInt tx = x;
   curve_mul(x, tx, m_r2, ws);
   }

void CurveGFp_Montgomery::from_curve_rep(BigInt& x, secure_vector<word>& ws) const
   {
   const BigInt tx = x;
   curve_mul(x, tx, 1, ws);
   }

void CurveGFp_Montgomery::curve_mul(BigInt& z, const BigInt& x, const BigInt& y,
                                    secure_vector<word>& ws) const
   {
   if(x.is_zero() || y.is_zero())
      {
      z = 0;
      return;
      }

   const size_t output_size = 2*m_p_words + 2;
   ws.resize(2*(m_p_words+2));

   if(z.size() < output_size)
      z.grow_to(output_size);
   z.clear();

   bigint_monty_mul(z, x, y,
                    m_p.data(), m_p_words, m_p_dash,
                    ws.data(), ws.size());
   }

void CurveGFp_Montgomery::curve_sqr(BigInt& z, const BigInt& x,
                                    secure_vector<word>& ws) const
   {
   if(x.is_zero())
      {
      z = 0;
      return;
      }

   const size_t x_sw = x.sig_words();
   BOTAN_ASSERT(x_sw <= m_p_words, "Input in range");

   const size_t output_size = 2*m_p_words + 2;

   ws.resize(2*(m_p_words+2));

   if(z.size() < output_size)
      z.grow_to(output_size);
   z.clear();

   bigint_monty_sqr(z, x, m_p.data(), m_p_words, m_p_dash,
                    ws.data(), ws.size());
   }

class CurveGFp_NIST : public CurveGFp_Repr
   {
   public:
      CurveGFp_NIST(size_t p_bits, const BigInt& a, const BigInt& b) :
         m_a(a), m_b(b), m_p_words((p_bits + BOTAN_MP_WORD_BITS - 1) / BOTAN_MP_WORD_BITS)
         {
         }

      const BigInt& get_a() const override { return m_a; }

      const BigInt& get_b() const override { return m_b; }

      size_t get_p_words() const override { return m_p_words; }

      const BigInt& get_a_rep() const override { return m_a; }

      const BigInt& get_b_rep() const override { return m_b; }

      void to_curve_rep(BigInt& x, secure_vector<word>& ws) const override
         { redc(x, ws); }

      void from_curve_rep(BigInt& x, secure_vector<word>& ws) const override
         { redc(x, ws); }

      void curve_mul(BigInt& z, const BigInt& x, const BigInt& y,
                     secure_vector<word>& ws) const override;

      void curve_sqr(BigInt& z, const BigInt& x,
                     secure_vector<word>& ws) const override;
   private:
      virtual void redc(BigInt& x, secure_vector<word>& ws) const = 0;

      // Curve parameters
      BigInt m_a, m_b;
      size_t m_p_words; // cache of m_p.sig_words()
   };

void CurveGFp_NIST::curve_mul(BigInt& z, const BigInt& x, const BigInt& y,
                              secure_vector<word>& ws) const
   {
   if(x.is_zero() || y.is_zero())
      {
      z = 0;
      return;
      }

   const size_t p_words = get_p_words();
   const size_t output_size = 2*p_words + 2;

   ws.resize(2*(p_words+2));

   if(z.size() < output_size)
      z.grow_to(output_size);
   z.clear();

   bigint_mul(z, x, y, ws.data(), ws.size());

   this->redc(z, ws);
   }

void CurveGFp_NIST::curve_sqr(BigInt& z, const BigInt& x,
                              secure_vector<word>& ws) const
   {
   if(x.is_zero())
      {
      z = 0;
      return;
      }

   const size_t p_words = get_p_words();
   const size_t output_size = 2*p_words + 2;

   ws.resize(2*(p_words+2));

   if(z.size() < output_size)
      z.grow_to(output_size);
   z.clear();

   bigint_sqr(z.mutable_data(), output_size,
              x.data(), x.size(), x.sig_words(),
              ws.data(), ws.size());

   this->redc(z, ws);
   }

#if defined(BOTAN_HAS_NIST_PRIME_REDUCERS_W32)

/**
* The NIST P-192 curve
*/
class CurveGFp_P192 final : public CurveGFp_NIST
   {
   public:
      CurveGFp_P192(const BigInt& a, const BigInt& b) : CurveGFp_NIST(192, a, b) {}
      const BigInt& get_p() const override { return prime_p192(); }
   private:
      void redc(BigInt& x, secure_vector<word>& ws) const override { redc_p192(x, ws); }
   };

/**
* The NIST P-224 curve
*/
class CurveGFp_P224 final : public CurveGFp_NIST
   {
   public:
      CurveGFp_P224(const BigInt& a, const BigInt& b) : CurveGFp_NIST(224, a, b) {}
      const BigInt& get_p() const override { return prime_p224(); }
   private:
      void redc(BigInt& x, secure_vector<word>& ws) const override { redc_p224(x, ws); }
   };

/**
* The NIST P-256 curve
*/
class CurveGFp_P256 final : public CurveGFp_NIST
   {
   public:
      CurveGFp_P256(const BigInt& a, const BigInt& b) : CurveGFp_NIST(256, a, b) {}
      const BigInt& get_p() const override { return prime_p256(); }
   private:
      void redc(BigInt& x, secure_vector<word>& ws) const override { redc_p256(x, ws); }
   };

/**
* The NIST P-384 curve
*/
class CurveGFp_P384 final : public CurveGFp_NIST
   {
   public:
      CurveGFp_P384(const BigInt& a, const BigInt& b) : CurveGFp_NIST(384, a, b) {}
      const BigInt& get_p() const override { return prime_p384(); }
   private:
      void redc(BigInt& x, secure_vector<word>& ws) const override { redc_p384(x, ws); }
   };

#endif

/**
* The NIST P-521 curve
*/
class CurveGFp_P521 final : public CurveGFp_NIST
   {
   public:
      CurveGFp_P521(const BigInt& a, const BigInt& b) : CurveGFp_NIST(521, a, b) {}
      const BigInt& get_p() const override { return prime_p521(); }
   private:
      void redc(BigInt& x, secure_vector<word>& ws) const override { redc_p521(x, ws); }
   };

}

std::shared_ptr<CurveGFp_Repr>
CurveGFp::choose_repr(const BigInt& p, const BigInt& a, const BigInt& b)
   {
#if defined(BOTAN_HAS_NIST_PRIME_REDUCERS_W32)
   if(p == prime_p192())
      return std::shared_ptr<CurveGFp_Repr>(new CurveGFp_P192(a, b));
   if(p == prime_p224())
      return std::shared_ptr<CurveGFp_Repr>(new CurveGFp_P224(a, b));
   if(p == prime_p256())
      return std::shared_ptr<CurveGFp_Repr>(new CurveGFp_P256(a, b));
   if(p == prime_p384())
      return std::shared_ptr<CurveGFp_Repr>(new CurveGFp_P384(a, b));
#endif

   if(p == prime_p521())
      return std::shared_ptr<CurveGFp_Repr>(new CurveGFp_P521(a, b));

   return std::shared_ptr<CurveGFp_Repr>(new CurveGFp_Montgomery(p, a, b));
   }

}
<|endoftext|>


<commit_before>#include <cmath>
#include <fstream>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_odeiv2.h>
#include "calc_u.h"

enum temperature_t { DOWN, UP, L_ACHIEVED };
class umax_achieved {};

std::string temperature_str (const temperature_t t)
{
    if (t == DOWN)
        return "DOWN";
    else
        return "UP";
}

real_t calc_z(const calc_u_Data &data)
{
    return data.nu * (1 + 3.762 * 28. / 32.);
}

inline real_t calc_Tb(const calc_u_Data& data)
{
    const real_t z = calc_z(data);
    return data.T0 + data.Q_div_cp * fmin(data.phi, 1) / (data.phi + z);
}

real_t U(const calc_u_Data &data, const real_t T)
{
    const real_t z = calc_z(data);
    return data.Q_div_cp * data.D * data.A * pow(T, data.n)
        * pow(data.phi / (data.phi + z) - (T - data.T0) / data.Q_div_cp, data.alpha)
        * pow(data.nu / (data.phi + z) - data.nu * (T - data.T0) / data.Q_div_cp, data.beta)
        * (exp(- data.E_div_R / T) - exp(- data.E_div_R / data.T0));
}

temperature_t calc_temperature(const real_t u, const calc_u_Data &data, const int N_trapezoid)
{
    real_t Tb = calc_Tb(data);
    real_t h = (Tb - data.T0) / N_trapezoid;
    long double p = 0;
    for (int i = 0; i < N_trapezoid; ++i) {
        real_t Ti = data.T0 + h * i;
        real_t Ti1 = Ti + h;
        real_t D = u * u + 4 / h * (p * p / h + u * p - U(data, Ti) - U(data, Ti1));
        if (D < 0)
            return DOWN;
        p = h / 2 * (u + sqrt(D));
    }
    return UP;
}

struct rk_Data {
    calc_u_Data data;
    real_t u;
};

int func(double t, const double y[], double dydt[], void *params)
{
    rk_Data* rk_data = (rk_Data*)params;
    real_t Tb = calc_Tb(rk_data->data);
    if (y[0] < rk_data->data.T0 || y[0] > Tb) {
        dydt[0] = y[1];
        dydt[1] = 0;
    }
    else {
        dydt[0] = y[1];
        dydt[1] = rk_data->u * y[1] - U(rk_data->data, y[0]);
    }
    return GSL_SUCCESS;
}

temperature_t calc_temperature_rk (const real_t u, const calc_u_Data& data)
{
    const double L = 10000;
    const double eps_ic = 0.001;
    const double eps_abs = 1e-4;

    const gsl_odeiv2_step_type *T = gsl_odeiv2_step_rkf45;
    gsl_odeiv2_step *s = gsl_odeiv2_step_alloc(T, 2);
    gsl_odeiv2_control *c = gsl_odeiv2_control_y_new(eps_abs, 0.0);
    gsl_odeiv2_evolve *e = gsl_odeiv2_evolve_alloc(2);

    rk_Data rk_data = { data, u };
    gsl_odeiv2_system sys = {func, NULL, 2, &rk_data};

    double t = -L, t1 = L;
    double h = 1e-6;
    double maxh = 1e-1;
    double y[2] = { data.T0, eps_ic };

    real_t Tb = calc_Tb(data);
    while (t < t1) {
        int status = gsl_odeiv2_evolve_apply(e, c, s, &sys, &t, t1, &h, y);
        if (status != GSL_SUCCESS) {
            printf ("error, return value=%d\n", status);
            break;
        }
        if (y[0] > Tb) {
            return UP;
        }
        if (y[1] < 0) {
            return DOWN;
        }
        if (h > maxh)
            h = maxh;
    }
    throw "L achieved";
    gsl_odeiv2_evolve_free(e);
    gsl_odeiv2_control_free(c);
    gsl_odeiv2_step_free(s);
    return L_ACHIEVED;
}

real_t calc_u (const calc_u_Data &data, const Config &config, const method_t method)
{
    real_t u = config.u_init / 2;
    temperature_t temperature_res = DOWN;
    while (u <= config.max_u && temperature_res == DOWN) {
        u *= 2;
        if (method == METHOD_TRAPEZOID)
            temperature_res = calc_temperature(u, data, config.N_trapezoid);
        else
            temperature_res = calc_temperature_rk(u, data);
    }
    if (u > config.max_u)
        throw umax_achieved();
    long double left = 0;
    long double right = u;
    while (right - left > config.u_eps) {
        u = (left + right) / 2;
        if (method == METHOD_TRAPEZOID)
            temperature_res = calc_temperature(u, data, config.N_trapezoid);
        else
            temperature_res = calc_temperature_rk(u, data);
        if (temperature_res == UP)
            right = u;
        else if (temperature_res == DOWN)
            left = u;
    }
    return u;
}
<commit_msg>Add #ifdef RUNGE_KUTTA<commit_after>#include <cmath>
#include <fstream>
#include "calc_u.h"

#ifdef RUNGE_KUTTA
#include <gsl/gsl_errno.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_odeiv2.h>
#endif

enum temperature_t { DOWN, UP, L_ACHIEVED };
class umax_achieved {};

std::string temperature_str (const temperature_t t)
{
    if (t == DOWN)
        return "DOWN";
    else
        return "UP";
}

real_t calc_z(const calc_u_Data &data)
{
    return data.nu * (1 + 3.762 * 28. / 32.);
}

inline real_t calc_Tb(const calc_u_Data& data)
{
    const real_t z = calc_z(data);
    return data.T0 + data.Q_div_cp * fmin(data.phi, 1) / (data.phi + z);
}

real_t U(const calc_u_Data &data, const real_t T)
{
    const real_t z = calc_z(data);
    return data.Q_div_cp * data.D * data.A * pow(T, data.n)
        * pow(data.phi / (data.phi + z) - (T - data.T0) / data.Q_div_cp, data.alpha)
        * pow(data.nu / (data.phi + z) - data.nu * (T - data.T0) / data.Q_div_cp, data.beta)
        * (exp(- data.E_div_R / T) - exp(- data.E_div_R / data.T0));
}

temperature_t calc_temperature(const real_t u, const calc_u_Data &data, const int N_trapezoid)
{
    real_t Tb = calc_Tb(data);
    real_t h = (Tb - data.T0) / N_trapezoid;
    long double p = 0;
    for (int i = 0; i < N_trapezoid; ++i) {
        real_t Ti = data.T0 + h * i;
        real_t Ti1 = Ti + h;
        real_t D = u * u + 4 / h * (p * p / h + u * p - U(data, Ti) - U(data, Ti1));
        if (D < 0)
            return DOWN;
        p = h / 2 * (u + sqrt(D));
    }
    return UP;
}

struct rk_Data {
    calc_u_Data data;
    real_t u;
};

#ifdef RUNGE_KUTTA
int func(double t, const double y[], double dydt[], void *params)
{
    rk_Data* rk_data = (rk_Data*)params;
    real_t Tb = calc_Tb(rk_data->data);
    if (y[0] < rk_data->data.T0 || y[0] > Tb) {
        dydt[0] = y[1];
        dydt[1] = 0;
    }
    else {
        dydt[0] = y[1];
        dydt[1] = rk_data->u * y[1] - U(rk_data->data, y[0]);
    }
    return GSL_SUCCESS;
}

temperature_t calc_temperature_rk (const real_t u, const calc_u_Data& data)
{
    const double L = 10000;
    const double eps_ic = 0.001;
    const double eps_abs = 1e-4;

    const gsl_odeiv2_step_type *T = gsl_odeiv2_step_rkf45;
    gsl_odeiv2_step *s = gsl_odeiv2_step_alloc(T, 2);
    gsl_odeiv2_control *c = gsl_odeiv2_control_y_new(eps_abs, 0.0);
    gsl_odeiv2_evolve *e = gsl_odeiv2_evolve_alloc(2);

    rk_Data rk_data = { data, u };
    gsl_odeiv2_system sys = {func, NULL, 2, &rk_data};

    double t = -L, t1 = L;
    double h = 1e-6;
    double maxh = 1e-1;
    double y[2] = { data.T0, eps_ic };

    real_t Tb = calc_Tb(data);
    while (t < t1) {
        int status = gsl_odeiv2_evolve_apply(e, c, s, &sys, &t, t1, &h, y);
        if (status != GSL_SUCCESS) {
            printf ("error, return value=%d\n", status);
            break;
        }
        if (y[0] > Tb) {
            return UP;
        }
        if (y[1] < 0) {
            return DOWN;
        }
        if (h > maxh)
            h = maxh;
    }
    throw "L achieved";
    gsl_odeiv2_evolve_free(e);
    gsl_odeiv2_control_free(c);
    gsl_odeiv2_step_free(s);
    return L_ACHIEVED;
}
#endif

real_t calc_u (const calc_u_Data &data, const Config &config, const method_t method)
{
    real_t u = config.u_init / 2;
    temperature_t temperature_res = DOWN;
    while (u <= config.max_u && temperature_res == DOWN) {
        u *= 2;
#ifdef RUNGE_KUTTA
        if (method == METHOD_TRAPEZOID)
#endif
            temperature_res = calc_temperature(u, data, config.N_trapezoid);
#ifdef RUNGE_KUTTA
        else
            temperature_res = calc_temperature_rk(u, data);
#endif
    }
    if (u > config.max_u)
        throw umax_achieved();
    long double left = 0;
    long double right = u;
    while (right - left > config.u_eps) {
        u = (left + right) / 2;
#ifdef RUNGE_KUTTA
        if (method == METHOD_TRAPEZOID)
#endif
            temperature_res = calc_temperature(u, data, config.N_trapezoid);
#ifdef RUNGE_KUTTA
        else
            temperature_res = calc_temperature_rk(u, data);
#endif
        if (temperature_res == UP)
            right = u;
        else if (temperature_res == DOWN)
            left = u;
    }
    return u;
}
<|endoftext|>


<commit_before>#ifndef SUPERVISOR_H
#define	SUPERVISOR_H

class Supervisor
{
public:
   static void init();
   static void run [[noreturn]] ();
private:
   Supervisor();
   virtual ~Supervisor();
   Supervisor(const Supervisor& orig);
};

extern "C" void supervisor_init();

#endif	/* SUPERVISOR_H */

<commit_msg>use compiler specific annotations<commit_after>#ifndef SUPERVISOR_H
#define	SUPERVISOR_H

class Supervisor
{
public:
   static void init();
   static void run() __attribute__((noreturn));
private:
   Supervisor();
   virtual ~Supervisor();
   Supervisor(const Supervisor& orig);
};

extern "C" void supervisor_init();

#endif	/* SUPERVISOR_H */

<|endoftext|>


<commit_before>#ifndef STRLCPY_UTF8_HPP
#define STRLCPY_UTF8_HPP

namespace pqrs {
class strlcpy_utf8 {
public:
  static void
  strlcpy(char* dst, const char* src, size_t size) {
    // Do not use nullptr because kext build environment does not support it.
    if (dst == NULL) return;
    if (src == NULL) return;
    if (size == 0) return;

    ::strlcpy(dst, src, size);

    size_t len = strlen(dst);

    // removing an incomplete multi-byte character at tail.
    size_t i = 0;
    size_t previous = 0;
    while (true) {
      previous = i;

      if ((dst[i] & 0x80) == 0) { // 0xxxxxxx
        ++i;
      } else if ((dst[i] & 0xe0) == 0xc0) { // 110xxxxx
        i += 2;
      } else if ((dst[i] & 0xf0) == 0xe0) { // 1110xxxx
        i += 3;
      } else if ((dst[i] & 0xf8) == 0xf0) { // 11110xxx
        i += 4;
      } else {
        break;
      }

      if (i > len) {
        break;
      }
    }
    dst[previous] = '\0';
  }
};
}

#endif
<commit_msg>add final specifier<commit_after>#ifndef STRLCPY_UTF8_HPP
#define STRLCPY_UTF8_HPP

namespace pqrs {
class strlcpy_utf8 final {
public:
  static void
  strlcpy(char* dst, const char* src, size_t size) {
    // Do not use nullptr because kext build environment does not support it.
    if (dst == NULL) return;
    if (src == NULL) return;
    if (size == 0) return;

    ::strlcpy(dst, src, size);

    size_t len = strlen(dst);

    // removing an incomplete multi-byte character at tail.
    size_t i = 0;
    size_t previous = 0;
    while (true) {
      previous = i;

      if ((dst[i] & 0x80) == 0) { // 0xxxxxxx
        ++i;
      } else if ((dst[i] & 0xe0) == 0xc0) { // 110xxxxx
        i += 2;
      } else if ((dst[i] & 0xf0) == 0xe0) { // 1110xxxx
        i += 3;
      } else if ((dst[i] & 0xf8) == 0xf0) { // 11110xxx
        i += 4;
      } else {
        break;
      }

      if (i > len) {
        break;
      }
    }
    dst[previous] = '\0';
  }
};
}

#endif
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2013, Ben Noordhuis <info@bnoordhuis.nl>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include "compat.h"
#include "compat-inl.h"
#include "v8.h"
#include "node.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <signal.h>
#include <cxxabi.h>
#include <dlfcn.h>

#if !defined(__linux__) && !defined(__APPLE__)
# error "Unsupported platform. Only Linux and OS work."
#endif

#if !defined(__i386__) && !defined(__x86_64__)
# error "Unsupported architecture. Only i386 and x86_64 work."
#endif

extern "C" {
void jsbacktrace(v8::Isolate* isolate);
}

namespace
{

namespace C = ::compat;

#define OFFSET(base, addr)                                                    \
  (static_cast<long>(static_cast<const char*>(addr) -                         \
                     static_cast<const char*>(base)))

// Assumes -fno-omit-frame-pointer.
struct Frame
{
  const Frame* frame_pointer;
  const void* return_address;
};

// Linked list. Wildly inefficient.
struct Code
{
  Code* next;
  const void* start;
  const void* end;
  char name[1];  // Variadic length.
};

void sigabrt(int);
void find_stack_top(void*, const Frame* frame);
void walk_stack_frames(unsigned skip, void (*cb)(void* arg, const Frame* frame),
                       void* arg);
C::ReturnType backtrace(const C::ArgumentType& args);
void print_stack_frame(void* arg, const Frame* frame);
bool print_c_frame(const Frame* frame, FILE* stream);
bool print_js_frame(v8::Isolate* isolate, const Frame* frame, FILE* stream);
Code* find_code(const void* addr);
void add_code(const char* name,
              unsigned int namelen,
              const void* start,
              const void* end);
void free_code();
void jit_code_event(const v8::JitCodeEvent* ev);

struct Code* code_head;
int stack_trace_index;
v8::Isolate* main_isolate;
v8::Local<v8::StackTrace> stack_trace;

const Frame* stack_top = reinterpret_cast<const Frame*>(-1);

void init(v8::Local<v8::Object> module)
{
  v8::Isolate* const isolate = main_isolate = v8::Isolate::GetCurrent();
  struct sigaction sa;
  memset(&sa, 0, sizeof(sa));
  sa.sa_flags = SA_RESETHAND;
  sa.sa_handler = sigabrt;
  sigaction(SIGABRT, &sa, NULL);
  walk_stack_frames(0, find_stack_top, NULL);
  module->Set(C::String::NewFromUtf8(isolate, "backtrace"),
              C::FunctionTemplate::New(isolate, backtrace)->GetFunction());
}

void find_stack_top(void*, const Frame* frame)
{
  Dl_info info;
  if (dladdr(frame->return_address, &info) == 0)
    return;
  if (info.dli_sname == NULL)
    return;
#if defined(__APPLE__)
  if (strcmp(info.dli_sname, "start") == 0)
    stack_top = frame->frame_pointer;
#elif defined(__linux__)
  // __libc_start_main() has no next frame pointer. Scanning for main() is not
  // safe because the compiler sometimes optimizes it away entirely.
  if (strcmp(info.dli_sname, "__libc_start_main") == 0)
    stack_top = frame;
#endif
}

C::ReturnType backtrace(const C::ArgumentType& args)
{
  C::ReturnableHandleScope handle_scope(args);
  jsbacktrace(args.GetIsolate());
  return handle_scope.Return();
}

void sigabrt(int)
{
  jsbacktrace(main_isolate);
  raise(SIGABRT);
}

// Externally visible.
extern "C" void jsbacktrace(v8::Isolate* isolate)
{
  walk_stack_frames(1, print_stack_frame, isolate);
  free_code();
}

void print_stack_frame(void* arg, const Frame* frame)
{
  FILE* stream = stderr;

  if (print_c_frame(frame, stream))
    return;

  if (print_js_frame(static_cast<v8::Isolate*>(arg), frame, stream))
    return;

  // Unresolved. Just print the raw address.
  fprintf(stream, "%lx\n", reinterpret_cast<long>(frame->return_address));
}

bool print_c_frame(const Frame* frame, FILE* stream)
{
  Dl_info info;

  if (dladdr(frame->return_address, &info) == 0)
    return false;

  const char* name = info.dli_sname;
  const char* demangled_name = abi::__cxa_demangle(name, NULL, NULL, NULL);

  if (demangled_name != NULL)
    name = demangled_name;

  fprintf(stream,
          "%lx+%lx\t%s %s(%p)\n",
          reinterpret_cast<long>(info.dli_saddr),
          OFFSET(info.dli_saddr, frame->return_address),
          name,
          info.dli_fname,
          info.dli_fbase);

  if (name == demangled_name)
    free(const_cast<char*>(name));

  return true;
}

bool print_js_frame(v8::Isolate* isolate, const Frame* frame, FILE* stream)
{
  if (code_head == NULL) {
    // Lazy init.
    C::Isolate::SetJitCodeEventHandler(isolate, v8::kJitCodeEventEnumExisting,
                                       jit_code_event);
    C::Isolate::SetJitCodeEventHandler(isolate, v8::kJitCodeEventDefault, NULL);
    stack_trace = C::StackTrace::CurrentStackTrace(isolate, 64);
    stack_trace_index = 0;
  }

  Code* code = find_code(frame->return_address);
  if (code == NULL)
    return false;

  if (stack_trace_index < stack_trace->GetFrameCount()) {
    v8::Local<v8::StackFrame> js_frame =
        stack_trace->GetFrame(stack_trace_index++);
    v8::String::Utf8Value function_name(js_frame->GetFunctionName());
    if (function_name.length() > 0) {
      v8::String::Utf8Value script_name(js_frame->GetScriptName());
      fprintf(stream,
              "%lx+%lx\t%s %s:%d:%d\n",
              reinterpret_cast<long>(code->start),
              OFFSET(code->start, frame->return_address),
              *function_name,
              *script_name,
              js_frame->GetLineNumber(),
              js_frame->GetColumn());
      return true;
    }
  }

  fprintf(stream,
          "%lx+%lx\t%s\n",
          reinterpret_cast<long>(code->start),
          OFFSET(code->start, frame->return_address),
          code->name);
  return true;
}

Code* find_code(const void* addr)
{
  for (Code* code = code_head; code != NULL; code = code->next)
    if (code->start <= addr && code->end >= addr)
      return code;
  return NULL;
}

void add_code(const char* name,
              unsigned int namelen,
              const void* start,
              const void* end)
{
  Code* code = static_cast<Code*>(malloc(sizeof(*code) + namelen));
  if (code == NULL) return;
  memcpy(code->name, name, namelen);
  code->name[namelen] = '\0';
  code->start = start;
  code->end = end;
  code->next = code_head;
  code_head = code;
}

void free_code()
{
  while (code_head != NULL) {
    Code* code = code_head;
    code_head = code->next;
    free(code);
  }
}

void jit_code_event(const v8::JitCodeEvent* ev)
{
  if (ev->type == v8::JitCodeEvent::CODE_ADDED) {
    add_code(ev->name.str,
             ev->name.len,
             ev->code_start,
             static_cast<const char*>(ev->code_start) + ev->code_len);
  }
}

__attribute__((noinline))
void walk_stack_frames(unsigned skip, void (*cb)(void* arg, const Frame* frame),
                       void* arg)
{
  const Frame* frame;

#if defined(__x86_64__)
  __asm__ __volatile__ ("mov %%rbp, %0" : "=g" (frame));
#elif defined(__i386__)
  __asm__ __volatile__ ("mov %%ebp, %0" : "=g" (frame));
#endif

  do
    if (skip == 0)
      cb(arg, frame);
    else
      skip -= 1;
  while ((frame = frame->frame_pointer) != NULL && frame < stack_top);
}

}  // anonymous namespace

NODE_MODULE(backtrace, init)
<commit_msg>backtrace: tweak printing of unresolved addresses<commit_after>/*
 * Copyright (c) 2013, Ben Noordhuis <info@bnoordhuis.nl>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include "compat.h"
#include "compat-inl.h"
#include "v8.h"
#include "node.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <signal.h>
#include <cxxabi.h>
#include <dlfcn.h>

#if !defined(__linux__) && !defined(__APPLE__)
# error "Unsupported platform. Only Linux and OS work."
#endif

#if !defined(__i386__) && !defined(__x86_64__)
# error "Unsupported architecture. Only i386 and x86_64 work."
#endif

extern "C" {
void jsbacktrace(v8::Isolate* isolate);
}

namespace
{

namespace C = ::compat;

#define OFFSET(base, addr)                                                    \
  (static_cast<long>(static_cast<const char*>(addr) -                         \
                     static_cast<const char*>(base)))

// Assumes -fno-omit-frame-pointer.
struct Frame
{
  const Frame* frame_pointer;
  const void* return_address;
};

// Linked list. Wildly inefficient.
struct Code
{
  Code* next;
  const void* start;
  const void* end;
  char name[1];  // Variadic length.
};

void sigabrt(int);
void find_stack_top(void*, const Frame* frame);
void walk_stack_frames(unsigned skip, void (*cb)(void* arg, const Frame* frame),
                       void* arg);
C::ReturnType backtrace(const C::ArgumentType& args);
void print_stack_frame(void* arg, const Frame* frame);
bool print_c_frame(const Frame* frame, FILE* stream);
bool print_js_frame(v8::Isolate* isolate, const Frame* frame, FILE* stream);
Code* find_code(const void* addr);
void add_code(const char* name,
              unsigned int namelen,
              const void* start,
              const void* end);
void free_code();
void jit_code_event(const v8::JitCodeEvent* ev);

struct Code* code_head;
int stack_trace_index;
v8::Isolate* main_isolate;
v8::Local<v8::StackTrace> stack_trace;

const Frame* stack_top = reinterpret_cast<const Frame*>(-1);

void init(v8::Local<v8::Object> module)
{
  v8::Isolate* const isolate = main_isolate = v8::Isolate::GetCurrent();
  struct sigaction sa;
  memset(&sa, 0, sizeof(sa));
  sa.sa_flags = SA_RESETHAND;
  sa.sa_handler = sigabrt;
  sigaction(SIGABRT, &sa, NULL);
  walk_stack_frames(0, find_stack_top, NULL);
  module->Set(C::String::NewFromUtf8(isolate, "backtrace"),
              C::FunctionTemplate::New(isolate, backtrace)->GetFunction());
}

void find_stack_top(void*, const Frame* frame)
{
  Dl_info info;
  if (dladdr(frame->return_address, &info) == 0)
    return;
  if (info.dli_sname == NULL)
    return;
#if defined(__APPLE__)
  if (strcmp(info.dli_sname, "start") == 0)
    stack_top = frame->frame_pointer;
#elif defined(__linux__)
  // __libc_start_main() has no next frame pointer. Scanning for main() is not
  // safe because the compiler sometimes optimizes it away entirely.
  if (strcmp(info.dli_sname, "__libc_start_main") == 0)
    stack_top = frame;
#endif
}

C::ReturnType backtrace(const C::ArgumentType& args)
{
  C::ReturnableHandleScope handle_scope(args);
  jsbacktrace(args.GetIsolate());
  return handle_scope.Return();
}

void sigabrt(int)
{
  jsbacktrace(main_isolate);
  raise(SIGABRT);
}

// Externally visible.
extern "C" void jsbacktrace(v8::Isolate* isolate)
{
  walk_stack_frames(1, print_stack_frame, isolate);
  free_code();
}

void print_stack_frame(void* arg, const Frame* frame)
{
  FILE* stream = stderr;

  if (print_c_frame(frame, stream))
    return;

  if (print_js_frame(static_cast<v8::Isolate*>(arg), frame, stream))
    return;

  // Unresolved. Just print the raw address.
  fprintf(stream, "%lx\n", reinterpret_cast<long>(frame->return_address));
}

bool print_c_frame(const Frame* frame, FILE* stream)
{
  Dl_info info;

  if (dladdr(frame->return_address, &info) == 0)
    return false;

  const char* name = info.dli_sname;
  const char* demangled_name = abi::__cxa_demangle(name, NULL, NULL, NULL);

  if (demangled_name != NULL)
    name = demangled_name;

  fprintf(stream,
          "%lx+%lx\t%s %s(%p)\n",
          reinterpret_cast<long>(info.dli_saddr),
          OFFSET(info.dli_saddr, frame->return_address),
          name ? name : "<unknown>",
          info.dli_fname,
          info.dli_fbase);

  if (name == demangled_name)
    free(const_cast<char*>(name));

  return true;
}

bool print_js_frame(v8::Isolate* isolate, const Frame* frame, FILE* stream)
{
  if (code_head == NULL) {
    // Lazy init.
    C::Isolate::SetJitCodeEventHandler(isolate, v8::kJitCodeEventEnumExisting,
                                       jit_code_event);
    C::Isolate::SetJitCodeEventHandler(isolate, v8::kJitCodeEventDefault, NULL);
    stack_trace = C::StackTrace::CurrentStackTrace(isolate, 64);
    stack_trace_index = 0;
  }

  Code* code = find_code(frame->return_address);
  if (code == NULL)
    return false;

  if (stack_trace_index < stack_trace->GetFrameCount()) {
    v8::Local<v8::StackFrame> js_frame =
        stack_trace->GetFrame(stack_trace_index++);
    v8::String::Utf8Value function_name(js_frame->GetFunctionName());
    if (function_name.length() > 0) {
      v8::String::Utf8Value script_name(js_frame->GetScriptName());
      fprintf(stream,
              "%lx+%lx\t%s %s:%d:%d\n",
              reinterpret_cast<long>(code->start),
              OFFSET(code->start, frame->return_address),
              *function_name,
              *script_name,
              js_frame->GetLineNumber(),
              js_frame->GetColumn());
      return true;
    }
  }

  fprintf(stream,
          "%lx+%lx\t%s\n",
          reinterpret_cast<long>(code->start),
          OFFSET(code->start, frame->return_address),
          code->name);
  return true;
}

Code* find_code(const void* addr)
{
  for (Code* code = code_head; code != NULL; code = code->next)
    if (code->start <= addr && code->end >= addr)
      return code;
  return NULL;
}

void add_code(const char* name,
              unsigned int namelen,
              const void* start,
              const void* end)
{
  Code* code = static_cast<Code*>(malloc(sizeof(*code) + namelen));
  if (code == NULL) return;
  memcpy(code->name, name, namelen);
  code->name[namelen] = '\0';
  code->start = start;
  code->end = end;
  code->next = code_head;
  code_head = code;
}

void free_code()
{
  while (code_head != NULL) {
    Code* code = code_head;
    code_head = code->next;
    free(code);
  }
}

void jit_code_event(const v8::JitCodeEvent* ev)
{
  if (ev->type == v8::JitCodeEvent::CODE_ADDED) {
    add_code(ev->name.str,
             ev->name.len,
             ev->code_start,
             static_cast<const char*>(ev->code_start) + ev->code_len);
  }
}

__attribute__((noinline))
void walk_stack_frames(unsigned skip, void (*cb)(void* arg, const Frame* frame),
                       void* arg)
{
  const Frame* frame;

#if defined(__x86_64__)
  __asm__ __volatile__ ("mov %%rbp, %0" : "=g" (frame));
#elif defined(__i386__)
  __asm__ __volatile__ ("mov %%ebp, %0" : "=g" (frame));
#endif

  do
    if (skip == 0)
      cb(arg, frame);
    else
      skip -= 1;
  while ((frame = frame->frame_pointer) != NULL && frame < stack_top);
}

}  // anonymous namespace

NODE_MODULE(backtrace, init)
<|endoftext|>


<commit_before>/// HEADER
#include "matrix_to_heatmap.h"

/// PROJECT
#include <csapex/utility/register_apex_plugin.h>
#include <csapex/model/connector_in.h>
#include <csapex/model/connector_out.h>
#include <utils_param/parameter_factory.h>
#include <utils_cv/heatmap.hpp>
#include <csapex_vision/cv_mat_message.h>

/// SYSTEM
#include <boost/assign/list_of.hpp>
#include <boost/function.hpp>

CSAPEX_REGISTER_CLASS(vision_plugins::MatrixToHeatmap, csapex::Node)

using namespace csapex;
using namespace csapex::connection_types;
using namespace vision_plugins;

MatrixToHeatmap::MatrixToHeatmap() :
    color_type_(BEZIER)
{
    Tag::createIfNotExists("Visualization");
    addTag(Tag::get("Visualization"));
    addTag(Tag::get("Vision"));

    std::map<std::string, int> types = boost::assign::map_list_of
            ("BEZIER", (int) BEZIER)
            ("PARABOLA", (int) PARABOLA);

    addParameter(param::ParameterFactory::declareParameterSet<int>("coloring", types),
                 boost::bind(&MatrixToHeatmap::update, this));

}

void MatrixToHeatmap::process()
{
    CvMatMessage::Ptr in = input_->getMessage<connection_types::CvMatMessage>();
    CvMatMessage::Ptr out(new connection_types::CvMatMessage(in->getEncoding()));

    cv::Mat working = in->value.clone();
    cv::Mat heatmap (working.rows, working.cols, CV_32FC3, cv::Scalar::all(0));
    cv::Mat mean    (working.rows, working.cols, CV_32FC1, cv::Scalar::all(0));
    cv::Mat mask;
    if(mask_->isConnected()) {
        CvMatMessage::Ptr mask_msg = mask_->getMessage<connection_types::CvMatMessage>();
        mask = mask_msg->value;
    } else {
        mask = cv::Mat(working.rows, working.cols, CV_8UC1, 255);
    }

    std::vector<cv::Mat> channels;
    cv::split(working, channels);

    for(std::vector<cv::Mat>::iterator it = channels.begin() ; it != channels.end() ; ++it) {
        it->convertTo(*it, CV_32FC1);
        mean += *it;
    }

    float divider = 1 / (float) channels.size();
    mean = mean * divider;

    utils_cv::colorFunction fc;
    switch(color_type_) {
    case BEZIER:
        fc = &utils_cv::bezierColor;
        break;
    case PARABOLA:
        fc = &utils_cv::parabolaColor;
        break;
    default:
        throw std::runtime_error("Unknown color function type!");
    }

    utils_cv::renderHeatmap(mean, heatmap, fc, mask);

    out->value = heatmap;
    output_->publish(out);
}

void MatrixToHeatmap::setup()
{
    setSynchronizedInputs(true);

    input_ = addInput<CvMatMessage>("Matrix");
    output_ = addOutput<CvMatMessage>("Heatmap");
    mask_   = addInput<CvMatMessage>("Mask",true);

    update();
}

void MatrixToHeatmap::update()
{
    color_type_ = (ColorType) param<int>("coloring");
}
<commit_msg>refactoring<commit_after>/// HEADER
#include "matrix_to_heatmap.h"

/// PROJECT
#include <csapex/utility/register_apex_plugin.h>
#include <csapex/model/connector_in.h>
#include <csapex/model/connector_out.h>
#include <utils_param/parameter_factory.h>
#include <utils_cv/heatmap.hpp>
#include <csapex_vision/cv_mat_message.h>

/// SYSTEM
#include <boost/assign/list_of.hpp>
#include <boost/function.hpp>

CSAPEX_REGISTER_CLASS(vision_plugins::MatrixToHeatmap, csapex::Node)

using namespace csapex;
using namespace csapex::connection_types;
using namespace vision_plugins;

MatrixToHeatmap::MatrixToHeatmap() :
    color_type_(BEZIER)
{
    Tag::createIfNotExists("Visualization");
    addTag(Tag::get("Visualization"));
    addTag(Tag::get("Vision"));

    std::map<std::string, int> types = boost::assign::map_list_of
            ("BEZIER", (int) BEZIER)
            ("PARABOLA", (int) PARABOLA);

    addParameter(param::ParameterFactory::declareParameterSet<int>("coloring", types),
                 boost::bind(&MatrixToHeatmap::update, this));

}

void MatrixToHeatmap::process()
{
    CvMatMessage::Ptr in = input_->getMessage<connection_types::CvMatMessage>();
    CvMatMessage::Ptr out(new connection_types::CvMatMessage(in->getEncoding()));

    cv::Mat working = in->value.clone();
    cv::Mat heatmap (working.rows, working.cols, CV_32FC3, cv::Scalar::all(0));
    cv::Mat mean    (working.rows, working.cols, CV_32FC1, cv::Scalar::all(0));
    cv::Mat mask;
    if(mask_->isConnected()) {
        CvMatMessage::Ptr mask_msg = mask_->getMessage<connection_types::CvMatMessage>();
        mask = mask_msg->value;
    } else {
        mask = cv::Mat(working.rows, working.cols, CV_8UC1, 255);
    }

    std::vector<cv::Mat> channels;
    cv::split(working, channels);

    for(std::vector<cv::Mat>::iterator it = channels.begin() ; it != channels.end() ; ++it) {
        it->convertTo(*it, CV_32FC1);
        mean += *it;
    }

    float divider = 1 / (float) channels.size();
    mean = mean * divider;

    utils_cv::Heatmap::colorFunction fc;
    switch(color_type_) {
    case BEZIER:
        fc = &utils_cv::Heatmap::bezierColor;
        break;
    case PARABOLA:
        fc = &utils_cv::Heatmap::parabolaColor;
        break;
    default:
        throw std::runtime_error("Unknown color function type!");
    }

    utils_cv::Heatmap::renderHeatmap(mean, heatmap, fc, mask);

    out->value = heatmap;
    output_->publish(out);
}

void MatrixToHeatmap::setup()
{
    setSynchronizedInputs(true);

    input_ = addInput<CvMatMessage>("Matrix");
    output_ = addOutput<CvMatMessage>("Heatmap");
    mask_   = addInput<CvMatMessage>("Mask",true);

    update();
}

void MatrixToHeatmap::update()
{
    color_type_ = (ColorType) param<int>("coloring");
}
<|endoftext|>