Public Key Recovery Operation

40 views
Skip to first unread message

Ricardo Alex

unread,
Nov 9, 2023, 6:54:44 AM11/9/23
to Crypto++ Users
According to https://www.secg.org/sec1-v2.pdf

  In section 4.1.6  Public Key Recovery Operation it' s possible to recover the public Key Q, at least to within a small number of choices,  given an ECDSA signature (r, s) and EC domain parameters.

  Input: The public key recovery operations takes as input: 

1. Elliptic curve domain parameters T = (p, a, b, G, n, h) or T = (m, f(x), a, b, G, n, h) at the desired security level.
2. A message M. 
3. An ECDSA signature value (r, s) that is valid on message M for some public key to be determined.  

Is it possible to achieve that using the crypto++ library? 

Ricardo Alex

unread,
Nov 9, 2023, 9:05:19 AM11/9/23
to Crypto++ Users
I am trying to follow the instructions in  https://www.secg.org/sec1-v2.pdf section  4.1.6
  Output: An elliptic curve public key Q for which (r, s) is a valid signature on message M. 
Actions: Find public key Q as follows. 
1. For j from 0 to h do the following. 1.1. Let x = r + jn. 
1.2. Convert the integer x to an octet string X of length mlen using the conversion routine specified in Section 2.3.7, where mlen = d(log2 p)/8e or mlen = dm/8e. 
1.3. Convert the octet string 0216kX to an elliptic curve point R using the conversion routine specified in Section 2.3.4. If this conversion routine outputs “invalid”, then do another iteration of Step 1. 
1.4. If nR 6= O, then do another iteration of Step 1. 1.5. Compute e from M using Steps 2 and 3 of ECDSA signature verification. 1.6. For k from 1 to 2 do the following. 1.6.1. Compute a candidate public key as: Q = r −1 (sR − eG).

The code so far:

 DL_GroupParameters_EC<ECP> params = ASN1::secp256k1();

Integer r("eefd86d83fd068cf979cfb11bf0696c66fc568ee342319a733ac9e804d6ea88d");
Integer s("0c12365ddc49f1b631c4c4a80764f8938afdd05563e00cff367da7cb715fccf1");

std::string message = "e9128504a817c80082520894787945765ac5a4f186a13e702664d6ecb78f57b68203e880830138818080";
byte hash[CryptoPP::SHA256::DIGESTSIZE];
SHA256().CalculateDigest(hash, (const byte*)message.data(), message.size());

Integer e(hash, CryptoPP::SHA256::DIGESTSIZE);

for (int j = 0; j <= params.GetCofactor(); ++j)
{
Integer x = r + j * params.GetSubgroupOrder();

SecByteBlock xBytes(x.MinEncodedSize());
x.Encode(xBytes.BytePtr(), xBytes.SizeInBytes());

ECP::Point R;
if (!params.GetCurve().DecodePoint(R, xBytes, xBytes.SizeInBytes()))
{
std::cout << "Invalid point. Trying another iteration." << std::endl;
continue;
}

if (!params.GetCurve().Multiply(e, R).identity)
{
std::cout << "nR is not the point at infinity. Trying another iteration." << std::endl;
continue;
}

for (int k = 1; k <= 2; ++k)
{
// Compute a candidate public key ...

}


Any Idea how to compute a candidate public key  considering according to manual it is  Q = r −1 (sR − eG)?
Reply all
Reply to author
Forward
0 new messages