Is there public key initialization API with point compression? - crypto++

I am tumbling around with CryptoPP and cannot find answer to this specific question. Here is sample source code (partial)
AutoSeededRandomPool prng;
//Generate a private key
ECDSA<ECP, CryptoPP::SHA256>::PrivateKey privateKey;
privateKey.Initialize(prng, CryptoPP::ASN1::secp256r1());
// Generate publicKey
ECDSA<ECP, CryptoPP::SHA256>::PublicKey publicKey;
privateKey.MakePublicKey(publicKey);
// Extract Component values
Integer p = privateKey.GetGroupParameters().GetCurve().GetField().GetModulus();
Integer a = privateKey.GetGroupParameters().GetCurve().GetA();
Integer b = privateKey.GetGroupParameters().GetCurve().GetB();
Integer Gx = privateKey.GetGroupParameters().GetSubgroupGenerator().x;
Integer Gy = privateKey.GetGroupParameters().GetSubgroupGenerator().y;
Integer n = privateKey.GetGroupParameters().GetSubgroupOrder();
Integer h = privateKey.GetGroupParameters().GetCofactor();
Integer Qx = publicKey.GetPublicElement().x;
Integer Qy = publicKey.GetPublicElement().y;
Integer x = privateKey.GetPrivateExponent();
// Construct Point elelemt;
ECP curve(p,a,b);
ECP::Point G(Gx,Gy);
ECP::Point Q(Qx,Qy);
//Build publicKey using elements (no point compression)
ECDSA<ECP, CryptoPP::SHA256>::PublicKey GeneratedPublicKey;
GeneratedPublicKey.Initialize(curve,G,n,Q);
assert(GeneratedPublicKey.Validate(prng, 3));
//Build publicKey using elements (with point compression)?
With this way, I can generate publicKey using component values. However, I cannot
make it work with point compression-which means I don't have Qy value- Is there a
way to do it? Initialize method has two overloading but none of them are for point
compression situation.
My question is specific with Crypto++ on "PublicKey.Initialize(curve,G,n,Q)". Since I cannot transfer whole publicKey with my current project-which I am force to specify domain
parameter as index value and can only transfer Qx value. So I should initialize publicKey
using something like "PublicKey.Initialize(curve,G,n,Q)" However, I cannot find such initialization API concerning point compression.
So, this is not about "how to do a point compression" but "Is there a way to initialize
public key without having Qy value?"

How to Construct ECDSA publicKey using only with x value (Point compression)?
x is the private exponent. The public key is a point on the curve; and it does not use the private exponent.
To get the public key: take the private exponent, and raise your base point to it. That is, Q = G^x.
If you want to set the private exponent on a private key or decryptor, then set the domain parameters (i.e., DL_GroupParameters_EC< ECP > or DL_GroupParameters_EC< EC2M >) and then call SetPrivateExponent(x);.
Have you reviewed your previous question at How can I recover compressed y value from sender?? The community took the time to provide you with an answer and sample code, but you did not acknowledge or follow up.
I think owlstead said it best here:
Why would we care answer you if you are not inclined to accept answers
or even follow up to them? Your questions are all right, but the way
you treat the community is terrible.

"Is there a way to initialize public key without having Qy value?"
Yes, there is. Here is an crypto++ example:
#include <string>
#include <iostream>
#include <cryptopp/cryptlib.h>
#include <cryptopp/ecp.h>
#include <cryptopp/eccrypto.h>
#include <cryptopp/hex.h>
#include <cryptopp/oids.h>
#include <cryptopp/osrng.h>
using namespace CryptoPP;
using std::cout;
using std::endl;
int main()
{
OID curve = ASN1::secp256r1();
ECDH<ECP>::Domain domain(curve);
SecByteBlock privKey(domain.PrivateKeyLength());
SecByteBlock pubKey(domain.PublicKeyLength());
AutoSeededRandomPool prng;
domain.GenerateKeyPair(prng, privKey, pubKey);
// Convert public key to string representation
std::string pub_str;
HexEncoder encoder;
encoder.Attach( new StringSink(pub_str) );
encoder.Put( pubKey.data(), pubKey.size() );
encoder.MessageEnd();
// Uncompressed point - first byte '04' in front of the string.
std::cout << "Uncompressed public key (point) " << pub_str << endl;
// Extract x value from the point
std::string public_point_x = pub_str.substr(2, 64);
// Compressed - '02' byte in front of the string.
public_point_x = "02" + public_point_x;
std::cout << "Compressed public key (point) " << public_point_x << endl;
// ----- reconstruct point from compressed point/value.
StringSource ss(public_point_x, true, new HexDecoder);
ECP::Point point;
domain.GetGroupParameters().GetCurve().DecodePoint(point, ss, ss.MaxRetrievable());
cout << "Result after decompression X: " << std::hex << point.x << endl;
cout << "Result after decompression Y: " << std::hex << point.y << endl;
return 0;
}
I hope this is the answer to your question. I was using ECDH, but it should work equally well with ECDSA class.

Related

About extending a Look Up Table at compile time

I'd like to extend my instrumental Profiler in order to avoid it affect too much performances.
Im my current implementation, I'm using a ProfilerHelper taking one string, which is put whereever you want in the profiling f().
The ctor is starting the measurement and the dector is closing it, logging the Delta in an unordered_map entry, which is key is the string.
Now, I'd like to turn all of that into a faster stuff.
First of all, I'd like to create a string LUT (Look Up Table) contaning the f()s names at compile time, and turn the unordered_map to a plain vector which is paired by the string function LUT.
Now the question is: I've managed to create a LUT but std::string_view, but I cannot find a way to extend it at compile time.
A first rought trial sounds like this:
template<unsigned N>
constexpr auto LUT() {
std::array<std::string_view, N> Strs{};
for (unsigned n = 0; n < N; n++) {
Strs[n] = "";
}
return Strs;
};
constexpr std::array<std::string_view, 0> StringsLUT { LUT<0>() };
constexpr auto AddString(std::string_view const& Str)
{
constexpr auto Size = StringsLUT.size();
std::array<std::string_view, Size + 1> Copy{};
for (auto i = 0; i < Size; ++i)
Copy[i] = StringsLUT[i];
Copy[Size] = Str;
return Copy;
};
int main()
{
constexpr auto Strs = AddString(__builtin_FUNCTION());
//for (auto const Str : Strs)
std::cout << Strs[0] << std::endl;
}
So my idea should be to recall the AddString whenever needed in my f()s to be profiled, extending this list at compile time.
But of course I should take the returned Copy and replace the StringsLUT everytime, to land to a final StringsLUT with all the f() names inside it.
Is there a way to do that at compile time?
Sorry, but I'm just entering the magic "new" world of constexpr applied to LUT right in these days.
Tx for your support in advance.

Parse a ECC private key buffer

I am using OPTEE-OS and mbedTLS and want to create a CSR. I am creating my EC key using the Global Platform API:
res = TEE_AllocateTransientObject(
TEE_TYPE_ECDSA_KEYPAIR,
DSEC_ECDSA_SHA256_KEY_BITS,
&key_pair);
if (res != TEE_SUCCESS) {
return res;
}
Then extract the private key:
res = TEE_GetObjectBufferAttribute(
key_pair,
TEE_ATTR_ECC_PRIVATE_VALUE,
buffer,
&bufferlen);
if (res != TEE_SUCCESS) {
return res;
}
Then use mbedTLS to parse this value and create a to create a CSR:
mbedtls_pk_context priv_key;
mbedtls_pk_init(&priv_key);
ret = mbedtls_pk_parse_key(
&priv_key,
key,
size,
NULL ,
0
);
However, the extracted value from TEE_GetObjectBufferAttribute does not have the headers and footpage:
"-----BEGIN EC PRIVATE KEY-----"
"-----END EC PRIVATE KEY-----"
and is only a binary array (not a string). I am currently getting the following error code: "-15616: PK - Invalid key tag or value".
Is there any way to create a mbedtls_pk_context with only the binary value of my private key?
The parsing functions in Mbed TLS's pk.h expect DER or PEM input. If you can find ready-made code to export a key as DER (or PEM) from OPTEE, that'll be easier (but possibly marginally less efficient). On the other hand, it's easier to do the import manually than to write a DER export function.
You need to call mbedtls_pk_setup() to declare that the context will contain an ECC key, then build the ECC key directly using the interface in ecp.h. Convert the curve designation from the TEE encoding to the Mbed TLS encoding, and calculate the public key from the private value. (Alternatively, you could export TEE_ATTR_ECC_PUBLIC_VALUE and set ec->Q, but that's more work.)
mbedtls_ecp_grp_id grp_id = …; // you need to convert this from the `TEE_ATTR_ECC_CURVE`
mbedtls_pk_context pk;
mbedtls_ecp_keypair *ec = malloc(sizeof(mbedtls_ecp_keypair));
mbedtls_pk_init(&pk);
mbedtls_pk_setup(&pk, mbedtls_pk_info_from_type(MBEDTLS_PK_ECDSA));
mbedtls_ecp_keypair_init(ec);
mbedtls_ecp_group_load(&ec->grp, grp_id);
mbedtls_mpi_read_binary(&ec->d, buffer, bufferlen);
mbedtls_ecp_check_privkey(&ec->grp, &ec->d);
mbedtls_ecp_mul(&ec->grp, &ec->Q, &ec->d, &ec->grp.G, mbedtls_ctr_drbg_random, &ctr_drbg);
pk->pk_ctx = ec;
Completely untested. Error checking omitted. ctr_drbg is a CTR_DRBG instance, used for blinding during the calculation of the public key.
To add to the accepted answer here is the code to import Q if there are X and Y available as buffers. And I guess those are available since in order to create an ECDSA key in OPTEE using GlobalPlatform crypto API all 4 attributes (TEE_ATTR_xxx) are required (d, Q(X,Y) and the curve id)
rc = mbedtls_mpi_read_binary(&ec->Q.X, buffer_x, buffer_x_size);
rc = mbedtls_mpi_read_binary(&ec->Q.Y, buffer_y, buffer_y_size);
rc = mbedtls_mpi_lset(&ec->Q.Z, 1);
rc = mbedtls_ecp_check_pubkey(&ec->grp, &ec->Q);

Read cv::Mat pixel without knowing its pixel format

I am aware there are several ways to read and write a pixel value of an OpenCV cv::Mat image/matrix.
A common one is the .at<typename T>(int, int) method http://opencv.itseez.com/2.4/modules/core/doc/basic_structures.html#mat-at .
However, this requires the typename to be known, for instance .at<double>.
The same thing applies to more direct pointer access OpenCV get pixel channel value from Mat image .
How can I read a pixel value without knowing its type? For instance, it would be ok to receive a more generic CvScalar value in return. Efficiency is not an issue, as I would like to read rather small matrices.
Kind of. You can construct cv::Mat_ and provide explicit type for elements, after that you don't have to write element type each time. Quoting opencv2/core/mat.hpp
While Mat is sufficient in most cases, Mat_ can be more convenient if you use a lot of element
access operations and if you know matrix type at the compilation time. Note that
Mat::at(int y,int x) and Mat_::operator()(int y,int x) do absolutely the same
and run at the same speed, but the latter is certainly shorter.
Mat_ and Mat are very similar. Again quote from mat.hpp:
The class Mat_<_Tp> is a thin template wrapper on top of the Mat class. It does not have any
extra data fields. Nor this class nor Mat has any virtual methods. Thus, references or pointers to
these two classes can be freely but carefully converted one to another.
You can use it like this
Mat_<Vec3b> dummy(3,3);
dummy(1, 2)[0] = 10;
dummy(1, 2)[1] = 20;
dummy(1, 2)[2] = 30;
cout << dummy(1, 2) << endl;
Why I said 'kind of' in the first place? Because if you want to pass this Mat_ somewhere - you have to specify it's type. Like this:
void test(Mat_<Vec3b>& arr) {
arr(1, 2)[0] = 10;
arr(1, 2)[1] = 20;
arr(1, 2)[2] = 30;
cout << arr(1, 2) << endl;
}
...
Mat_<Vec3b> dummy(3,3);
test(dummy);
Technically, you are not specifying your type during a pixel read, but actually you still have to know it and cast the Mat to the appropriate type beforehand.
I guess you can find a way around this using some low-level hacks (for example make a method that reads Mat's type, calculates element size and stride, and then accesses raw data using pointer arithmetic and casting...). But I don't know any 'clean' way to do this using OpenCV's functionality.
If you already know the type, you can use Mat_<> type for easy access. If you don't know the type, you can:
convert the data to double, so data won't be truncated in any case
switch over the number of channels to access correctly the double matrix. Note that you can have at most of 4 channels, since Scalar has at most 4 elements.
The following code will convert only the selected element of the source matrix to a double value (with N channels).
You get a Scalar containing the value at position row, col in the source matrix.
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
Scalar valueAt(const Mat& src, int row, int col)
{
Mat dst;;
src(Rect(col, row, 1, 1)).convertTo(dst, CV_64F);
switch (dst.channels())
{
case 1: return dst.at<double>(0);
case 2: return dst.at<Vec2d>(0);
case 3: return dst.at<Vec3d>(0);
case 4: return dst.at<Vec4d>(0);
}
return Scalar();
}
int main()
{
Mat m(3, 3, CV_32FC3); // You can use any type here
randu(m, Scalar(0, 0, 0, 0), Scalar(256, 256, 256, 256));
Scalar val = valueAt(m, 1, 2);
cout << val << endl;
return 0;
}

Print cv::Mat opencv

I am trying to print cv::Mat which contains my image. However whenever I print the Mat using cout, a 2D array printed into my text file. I want to print one one pixel in one line only. How can i print line wise pixels from cv::Mat.
A generic for_each loop, you could use it to print your data
/**
*#brief implement details of for_each_channel, user should not use this function
*/
template<typename T, typename UnaryFunc>
UnaryFunc for_each_channel_impl(cv::Mat &input, int channel, UnaryFunc func)
{
int const rows = input.rows;
int const cols = input.cols;
int const channels = input.channels();
for(int row = 0; row != rows; ++row){
auto *input_ptr = input.ptr<T>(row) + channel;
for(int col = 0; col != cols; ++col){
func(*input_ptr);
input_ptr += channels;
}
}
return func;
}
use it like
for_each_channel_impl<uchar>(input, 0, [](uchar a){ std::cout<<(size_t)a<<", "; });
you could do some optimization to continuous channel, then it may looks like
/**
*#brief apply stl like for_each algorithm on a channel
*
* #param
* T : the type of the channel(ex, uchar, float, double and so on)
* #param
* channel : the channel need to apply for_each algorithm
* #param
* func : Unary function that accepts an element in the range as argument
*
*#return :
* return func
*/
template<typename T, typename UnaryFunc>
inline UnaryFunc for_each_channel(cv::Mat &input, int channel, UnaryFunc func)
{
if(input.channels() == 1 && input.isContinuous()){
return for_each_continuous_channels<T>(input, func);
}else{
return for_each_channel_impl<T>(input, channel, func);
}
}
This kind of generic loopsave me a lot of times, I hope you find it helpful.If there are
any bugs, or you have better idea, please tell me.
I would like to design some generic algorithms for opencl too, sadly it do not support
template, I hope one day CUDA will become an open standard, or opencl will support template.
This works for any number of channels as long as the channels type are base on byte, non-byte
channel may not work.

Recasting *void function arguments

I posted a question here earlier that I think I can answer if someone can help me with the following:
I have a function
double func(void* data)
I want to pass in an object or struct. (In my case an armadillo matrix or even just and std::vector).
How do I pass a pointer to an object as an argument to func() and then, once inside func(), how do I recast the void pointer into its original type?
Edit: Here's what ended up working, where mat is the Armadillo matrix class:
mat A(2,2);
A << 1 << 2 << endr << 3 << 4; // A=[1,2; 3,4]
func(&A);
and in func:
double func(void* data) {
mat* pB = (mat*)(data);
mat B = pB[0];
}
The matrix B and A now contain the same data.
If I understand you correctly you need something like this.
double func(void* data_v) {
struct my_type * data = data_v;
}
func((void*)my_data);

Resources