I've read through the whitepapers and specifications relating to blind signatures which I've been able to come across, inclusive of the Wikipedia entries, but these tend to focus on the mathematical theory behind it.
Is there a concise practical implementation of RSA blind signatures within c++ using the Crypto++ library?
Is there a concise practical implementation of RSA blind signatures within c++ using the Crypto++ library?
Yes. The Crypto++ wiki has a section on blind signatures for RSA at Raw RSA | RSA Blind Signature. Below is the code taken from the wiki.
Crypto++ lacks blind signature classes. The method below follows the basic algorithm as detailed at Blind Signatures. However, it differs from Wikipedia by applying the s(s'(x)) = x cross-check. The cross-check was present in Chaum's original paper, but it is missing from the wiki article. A second difference from Chaum's paper and wikipedia is, the code below uses H(m) rather than m. That's due to Rabin in 1979.
As far as we know there is no standard covering the signature scheme. The lack of standardization will surely cause interop problems. For example, the code below uses SHA256 to hash the message to be signed, while RSA Blind Signature Scheme for golang uses full domain hashing. Also see Is there a standard padding/format for RSA Blind Signatures? on Crypto.SE.
You may want to apply a padding function first per Usability of padding scheme in blinded RSA signature? or RSA blind signatures in practice.
#include "cryptlib.h"
#include "integer.h"
#include "nbtheory.h"
#include "osrng.h"
#include "rsa.h"
#include "sha.h"
using namespace CryptoPP;
#include <iostream>
#include <stdexcept>
using std::cout;
using std::endl;
using std::runtime_error;
int main(int argc, char* argv[])
{
// Bob artificially small key pair
AutoSeededRandomPool prng;
RSA::PrivateKey privKey;
privKey.GenerateRandomWithKeySize(prng, 64);
RSA::PublicKey pubKey(privKey);
// Convenience
const Integer& n = pubKey.GetModulus();
const Integer& e = pubKey.GetPublicExponent();
const Integer& d = privKey.GetPrivateExponent();
// Print params
cout << "Pub mod: " << std::hex << pubKey.GetModulus() << endl;
cout << "Pub exp: " << std::hex << e << endl;
cout << "Priv mod: " << std::hex << privKey.GetModulus() << endl;
cout << "Priv exp: " << std::hex << d << endl;
// For sizing the hashed message buffer. This should be SHA256 size.
const size_t SIG_SIZE = UnsignedMin(SHA256::BLOCKSIZE, n.ByteCount());
// Scratch
SecByteBlock buff1, buff2, buff3;
// Alice original message to be signed by Bob
SecByteBlock orig((const byte*)"secret", 6);
Integer m(orig.data(), orig.size());
cout << "Message: " << std::hex << m << endl;
// Hash message per Rabin (1979)
buff1.resize(SIG_SIZE);
SHA256 hash1;
hash1.CalculateTruncatedDigest(buff1, buff1.size(), orig, orig.size());
// H(m) as Integer
Integer hm(buff1.data(), buff1.size());
cout << "H(m): " << std::hex << hm << endl;
// Alice blinding
Integer r;
do {
r.Randomize(prng, Integer::One(), n - Integer::One());
} while (!RelativelyPrime(r, n));
// Blinding factor
Integer b = a_exp_b_mod_c(r, e, n);
cout << "Random: " << std::hex << b << endl;
// Alice blinded message
Integer mm = a_times_b_mod_c(hm, b, n);
cout << "Blind msg: " << std::hex << mm << endl;
// Bob sign
Integer ss = privKey.CalculateInverse(prng, mm);
cout << "Blind sign: " << ss << endl;
// Alice checks s(s'(x)) = x. This is from Chaum's paper
Integer c = pubKey.ApplyFunction(ss);
cout << "Check sign: " << c << endl;
if (c != mm)
throw runtime_error("Alice cross-check failed");
// Alice remove blinding
Integer s = a_times_b_mod_c(ss, r.InverseMod(n), n);
cout << "Unblind sign: " << s << endl;
// Eve verifies
Integer v = pubKey.ApplyFunction(s);
cout << "Verify: " << std::hex << v << endl;
// Convert to a string
size_t req = v.MinEncodedSize();
buff2.resize(req);
v.Encode(&buff2[0], buff2.size());
// Hash message per Rabin (1979)
buff3.resize(SIG_SIZE);
SHA256 hash2;
hash2.CalculateTruncatedDigest(buff3, buff3.size(), orig, orig.size());
// Constant time compare
bool equal = buff2.size() == buff3.size() && VerifyBufsEqual(
buff2.data(), buff3.data(), buff3.size());
if (!equal)
throw runtime_error("Eve verified failed");
cout << "Verified signature" << endl;
return 0;
}
Here is the result of building and running the program:
$ g++ blind.cxx ./libcryptopp.a -o blind.exe
$ ./blind.exe
Pub mod: b55dc5e79993680fh
Pub exp: 11h
Priv mod: b55dc5e79993680fh
Priv exp: 1b4fc70ff2e97f1h
Message: 736563726574h
H(m): 2bb80d537b1da3e3h
Random: 72dd6819f0fc5e5fh
Blinded msg: 27a2e2e5e6f4fbfh
Blind sign: 84e7039495bf0570h
Check sign: 27a2e2e5e6f4fbfh
Unblind sign: 61054203e843f380h
Verify: 2bb80d537b1da3e3h
Verified signature
Related
I already have intel basekit installed, and eclipse for C / C ++: (eclipse-inst-jre-linux64.tar.gz), but I can't find a way to run a simple example using openmp.
In the terminal I compile my example with:
icpx -fiopenmp -fopenmp-targets = spir64 random_openmp.cpp
but I can't do the same using eclipse.
Please find the example code below:
# include <iostream>
# include <iomanip>
# include <cmath>
# include <ctime>
# include <omp.h>
using namespace std;
int main ( );
void monte_carlo ( int n, int &seed );
double random_value ( int &seed );
void timestamp ( );
/******************************************************************************/
int main ( void )
/******************************************************************************/
/*
Purpose:
MAIN is the main program for RANDOM_OPENMP.
Discussion:
This program simply explores one issue in the generation of random
numbers in a parallel program. If the random number generator uses
an integer seed to determine the next entry, then it is not easy for
a parallel program to reproduce the same exact sequence.
But what is worse is that it might not be clear how the separate
OpenMP threads should handle the SEED value - as a shared or private
variable? It seems clear that each thread should have a private
seed that is initialized to a distinct value at the beginning of
the computation.
Licensing:
This code is distributed under the GNU LGPL license.
Modified:
03 September 2012
Author:
John Burkardt
*/
{
int n;
int seed;
timestamp ( );
cout << "\n";
cout << "RANDOM_OPENMP\n";
cout << " C++ version\n";
cout << " An OpenMP program using random numbers.\n";
cout << " The random numbers depend on a seed.\n";
cout << " We need to insure that each OpenMP thread\n";
cout << " starts with a different seed.\n";
cout << "\n";
cout << " Number of processors available = " << omp_get_num_procs ( ) << "\n";
cout << " Number of threads = " << omp_get_max_threads ( ) << "\n";
n = 100;
seed = 123456789;
monte_carlo ( n, seed );
/*
Terminate.
*/
cout << "\n";
cout << "RANDOM_OPENMP\n";
cout << " Normal end of execution.\n";
cout << "\n";
timestamp ( );
return 0;
}
/******************************************************************************/
void monte_carlo ( int n, int &seed )
/******************************************************************************/
/*
Purpose:
MONTE_CARLO carries out a Monte Carlo calculation with random values.
Licensing:
This code is distributed under the GNU LGPL license.
Modified:
03 September 2012
Author:
John Burkardt
Parameter:
Input, int N, the number of values to generate.
Input, int &SEED, a seed for the random number generator.
*/
{
int i;
int my_id;
int *my_id_vec;
int my_seed;
int *my_seed_vec;
double *x;
x = new double[n];
my_id_vec = new int[n];
my_seed_vec = new int[n];
# pragma omp master
{
cout << "\n";
cout << " Thread Seed I X(I)\n";
cout << "\n";
}
# pragma omp parallel private ( i, my_id, my_seed ) shared ( my_id_vec, my_seed_vec, n, x )
{
my_id = omp_get_thread_num ( );
my_seed = seed + my_id;
cout << " " << setw(6) << my_id
<< " " << setw(12) << my_seed << "\n";
# pragma omp for
for ( i = 0; i < n; i++ )
{
my_id_vec[i] = my_id;
x[i] = random_value ( my_seed );
my_seed_vec[i] = my_seed;
// cout << " " << setw(6) << my_id
// << " " << setw(12) << my_seed
// << " " << setw(6) << i
// << " " << setw(14) << x[i] << "\n";
}
}
//
// C++ OpenMP IO from multiple processors comes out chaotically.
// For this reason only, we'll save the data from the loop and
// print it in the sequential section!
//
for ( i = 0; i < n; i++ )
{
cout << " " << setw(6) << my_id_vec[i]
<< " " << setw(12) << my_seed_vec[i]
<< " " << setw(6) << i
<< " " << setw(14) << x[i] << "\n";
}
delete [] my_id_vec;
delete [] my_seed_vec;
delete [] x;
return;
}
/******************************************************************************/
double random_value ( int &seed )
/******************************************************************************/
/*
Purpose:
RANDOM_VALUE generates a random value R.
Discussion:
This is not a good random number generator. It is a SIMPLE one.
It illustrates a model which works by accepting an integer seed value
as input, performing some simple operation on the seed, and then
producing a "random" real value using some simple transformation.
Licensing:
This code is distributed under the GNU LGPL license.
Modified:
03 September 2012
Author:
John Burkardt
Parameters:
Input/output, int &SEED, a seed for the random
number generator.
Output, double RANDOM_VALUE, the random value.
*/
{
double r;
seed = ( seed % 65536 );
seed = ( ( 3125 * seed ) % 65536 );
r = ( double ) ( seed ) / 65536.0;
return r;
}
//****************************************************************************80
void timestamp ( )
//****************************************************************************80
//
// Purpose:
//
// TIMESTAMP prints the current YMDHMS date as a time stamp.
//
// Example:
//
// 31 May 2001 09:45:54 AM
//
// Modified:
//
// 24 September 2003
//
// Author:
//
// John Burkardt
//
// Parameters:
//
// None
//
{
# define TIME_SIZE 40
static char time_buffer[TIME_SIZE];
const struct tm *tm;
time_t now;
now = time ( NULL );
tm = localtime ( &now );
strftime ( time_buffer, TIME_SIZE, "%d %B %Y %I:%M:%S %p", tm );
cout << time_buffer << "\n";
return;
# undef TIME_SIZE
}
There is an article explaining how to use Intel C++ compiler in Eclipse here:
https://software.intel.com/content/www/us/en/develop/articles/intel-c-compiler-for-linux-using-intel...
, also one more recent documentation on running a sample program in Eclipse here:
https://software.intel.com/content/www/us/en/develop/documentation/get-started-with-intel-oneapi-base-linux/top/run-a-sample-project-using-an-ide.html
and
https://software.intel.com/content/www/us/en/develop/documentation/get-started-with-intel-oneapi-hpc-linux/top/run-a-sample-project-with-eclipse.html
The HPCKit Get Start used the matrix sample. It has an OpenMP version. So you need to launch Eclipse from terminal window where the env is set with "servars.sh".
I'm writing a Lex code for scanning Verilog code, and I define a pattern that I want to match. But when I run the code, I find that the pattern I defined won't match. Where did I make a mistake?
I run the code on a Linux workstation. The flex version is 2.5.4.
%option c++
%option noyywrap
%{
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
vector<string> input_vec; /*To remember which signal is input*/
int input_num = 0; /*To count the # of input signals*/
%}
%x INPUT
var_string [a-z]+
%%
input {
cout << "BEGIN INPUT" << endl;
BEGIN INPUT;
}
[ \n\t\r\f]+
.
<INPUT>{var_string} {
cout << "IN INPUT MATCHING var_string:" << yytext << endl;
input_num++;
input_vec.push_back(yytext);
}
<INPUT>; {BEGIN 0;}
<INPUT>,
<INPUT>[ \n\t\r\f]+
%%
int main(int argc, char* argv[])
{
ifstream input_file("test.v");
FlexLexer* lexer;
lexer = new yyFlexLexer(&input_file, &cout);
while(lexer->yylex()!=0);
cout << "Input Number: " << input_num << endl;
return 0;
}
Here is the Verilog code I want to scan.
module test(a, b, c, sum, carry);
input
a,
b,
c;
output
sum,
carry;
wire
d;
assign
d = (~b & a) | (b & ~a),
sum = (d & c) | (d & ~c),
carry= (a & b) | (b & c) | (a & c);
endmodule
I except that when the Lex code scan a, b, and c in input section, the output will be:
BEGIN INPUT
IN INPUT MATCHING var_string:a
IN INPUT MATCHING var_string:b
IN INPUT MATCHING var_string:c
Input Number: 3
However, the real output is:
BEGIN INPUT
Input Number: 0
I need to create a card game for a school assignment and I am trying to display the heart, diamonds, spades, and clubs symbols in the output.
The teacher told us to use char(3), char(4), etc but the output shows a question mark. I'm using Visual Studio 2017 on Windows 10.
I am not too familiar with Unicode or ASCII stuff, if anyone could help me out, I still have 3 days to submit this assignment!! I'm a beginner
Thank you
//For COMP 218 Section EC (Winter 2017) - Concordia University
cout << char(3) << char(4) << char(5) << char(6) << char(3) << char(4) << char(5) << char(6) << char(3) << char(4) << char(5) << char(6) << endl
<< "\t \t Welcome to Shawn's Card Dealing Program" << endl
<< char(3) << char(4) << char(5) << char(6) << char(3) << char(4) << char(5) << char(6) << char(3) << char(4) << char(5) << char(6);
cout << "RULES: \nTwo cards are dealt at a time. They are then compared. \nSince there are two decks of cards, you may have identital cards. \nI will tell you if they are the same or not" << endl
<< "or if they just have the same suit or rank. \nOnce I finish comparing the two cards, they are returned to the deck, the deck is reshuffled and two more cards are dealt. \n \n" << endl
<< "So how many pairs shall I deal? (1 to 15 max): \n > ";
while (!valid)
{
valid = true;
cin >> loops;
if (cin.fail() || loops < 1 || loops > 15)
{
cin.clear();
cin.ignore();
cout << "Please enter an integer between 1 and 15:" << endl << "> ";
valid = false;
}
}
int pairCount = loops;
do
{
card1.genRandom();
card2.genRandom();
cout << "Pair " << setw(2) << pairCount - loops + 1 << " - ";
card1.printCard();
card2.printCard();
cout << endl;
if (card1.sameCard(card2) == true)
{
cout << "same card" << endl;
ident += 1;
}
else
{
if (card1.sameSuit(card2) == true)
{
cout << "same suit" << endl;
sameSuit +=1;
}
if (card1.sameRank(card2) == true)
{
cout << "same rank" << endl;
sameRank += 1;
}
if (card1.sameRank(card2) == false && card1.sameSuit(card2) == false)
{
cout << "both different" << endl;
different +=1;
}
}
loops -= 1;
} while (loops > 0);
cout << "Identical: " << ident << endl;
cout << "Same Suit: " << sameSuit << endl;
cout << "Same Rank: " << sameRank << endl;
cout << "Both different: " << different << endl;
}
You are probably not using ASCII and have actually been instructed to use a different encoding as evidenced by the requirement for playing card suit characters, which are not in the ASCII character set. (Pretty much any mention of ASCII without a reference to a specification is very suspect.)
You could be using CP437 (go chcp in your command prompt.) CP437 is one of the encodings where 3,4,5,6 are the playing card suits. It's possible that your system is conveniently set up with a command prompt encoding more useful for French. If so, you could just run chcp 437 each time you open a command prompt for this program.
For this to work, your command prompt also has to set for a font that supports the characters. I think the vast majority of fonts do support the playing card suit characters so this probably isn't an issue.
boost::icl::interval_map<int, boost::icl::interval_map<int, boost::icl::interval_set<int>>> larger, smaller;
larger.add(make_pair(boost::icl::discrete_interval<int>::closed(102,104),
boost::icl::interval_map<int, boost::icl::interval_set<int>>{
make_pair(boost::icl::discrete_interval<int>::closed(0,0), boost::icl::interval_set<int {boost::icl::discrete_interval<int>::closed(2,4)})}));
smaller.add(make_pair(boost::icl::discrete_interval<int>::closed(103,103),
boost::icl::interval_map<int, boost::icl::interval_set<int>>{
make_pair(boost::icl::discrete_interval<int>::closed(0,0), boost::icl::interval_set<int>{boost::icl::discrete_interval<int>::closed(3,3)})}));
cout << larger << endl;
cout << smaller << endl;
cout << boost::icl::contains(larger, smaller) << endl;
cout << ((smaller & larger) == smaller) << endl;
As given above, I'm trying to check if smaller is subset of larger. But I
get following output:
{([102,104]->{([0,0]->{[2,4]})})}
{([103,103]->{([0,0]->{[3,3]})})}
0
1
Any reason why boost::icl::contains(larger, smaller) doesn't work but
((smaller & larger) == smaller) works?
I want to have a goocanvas with a rect item which contains a text.
How to build a group with a rect to add the text as a child is known. But I want to know the size of the text to give the box ( rect ) enough space to display the complete text.
txt->property_width()
delivers 0! :-(
Glib::RefPtr<Goocanvas::Text> txt = Goocanvas::Text::create( "W123", 0, 0 );
Goocanvas::Bounds b = txt->get_bounds();
cout << b.get_x1() << endl;
cout << b.get_x2() << endl;
cout << b.get_y1() << endl;
cout << b.get_y2() << endl;
All values are zero!
Wow! If I change the code to:
Glib::RefPtr<Goocanvas::Text> txt = Goocanvas::Text::create( "W123", 0, 0 );
Goocanvas::Bounds b = txt->get_bounds();
GooCanvasBounds bounds;
goo_canvas_item_get_bounds (( GooCanvasItem*)txt->gobj(), &bounds);
cout << b.get_x1() << endl;
cout << b.get_x2() << endl;
cout << b.get_y1() << endl;
cout << b.get_y2() << endl;
The output is as expected! Attention: I look not at the bounds var! I still look for
'b'. Looks strange!
[Edit] I wrote a bug report: https://bugzilla.gnome.org/show_bug.cgi?id=721627
If your text is a GooCanvasText item, all you need is (in gtk+)
void goo_canvas_item_get_bounds (GooCanvasItem *item, GooCanvasBounds *bounds)
This translates to txt->get_bounds() in the gtkmm case. See goocanvas online devhelp for details.