Archived Forum Post

Index of archived forum posts

Question:

How to pass a R/S signature to CkDsa?

Apr 07 '13 at 18:19

Hello,

I'm attempting to use CkDsa to authenticate a signed S-63 certificate in the following format:

// Signature part R:

8FD6 2AC7 27D2 8D0B CD27 BDF2 5CC6 9656 10E3 751F.

// Signature part S:

3DE7 DA37 5A40 80FC 4203 5C6E 37DE A984 2A88 2BDC.

// BIG p

D0A0 2D76 D210 58DA 4D91 BBC7 30AC 9186 5CB4 036C CDA4 6B49 4650 16BB 6931 2F12

DF14 A0CC F38E B77C AD84 E6A1 2F2A A0D0 441A 734B 1D2B E944 5D10 BA87 609B 75E3.

// BIG q

8E00 82E3 C046 DFE6 C422 F44C C111 DBF6 ADEE 9467.

// BIG g

B08D 786D 0ED3 4E39 7C6B 3ACF 8843 C3BF BAB1 A44D 0846 BB2A C3EE D432 B270 E710

E083 B239 AF0E A5B8 693B F2FC A03B 6A73 E289 84FF 8623 1394 996F 6263 0845 AA94.

// BIG y

444B BA17 1758 0DAF 71AB 52A5 6CCA 8EAB 4C51 E970 0E37 B17B BB46 C0B9 4A36 F73F

0244 7FBD AE5B 7CA9 3870 5AB9 E9EE 471C E7B0 1004 6DF1 3505 42B3 0332 AE67 69C6.

I'm able to successfully pass the PQGY strings via CkDsa::SetPubKeyExplicit() and CkDsa::VerifyKey() returns true.

What I don't understand is how to pass the 'Signature Part R' and 'Signature Part S' encoded hex strings to CkDsa::SetEncodedSignature(). Do I simply concatentate the R and S strings together into a single string, or is there a specific string format I need to pass? The docs don't say much about this.

Thanks,

Barry


Answer

Barry,

A DSA signature is an ASN.1-encoded string formed like this:

      SEQUENCE {
      r INTEGER,
      s INTEGER
      }

Unfortunately, this is not as simple as concatenating R and S. I can try to provide a new build early next week with the ability to pass R and S separately. It should be very easy. Please post a comment here as a reminder on Monday or Tuesday.


Answer

Thanks. I'm willing to build the encoded string myself. I found the following comment at http://stackoverflow.com/questions/7068733/convert-java-to-python-dsa-signing. It looks to me like the encoding is as follows, please confirm:

Encoding is: 0x30 A 0x02 B R 0x02 C S

where:

•R is the big-endian signed encoding of r, of minimal length: this means that the first byte shall have a value between 0 and 127, and it shall have value 0 only if the second byte has a value between 128 and 255. In other words, encode r as a sequence of bytes with big-endian convention (most significant byte comes first), making sure that you have as few leading zero bits as possible, provided that you keep at least one (this is what the "signed" encoding means: since r is positive, its most significant bit must be 0). Since r is an integer between 0 and q-1, the length of R will be at most one more byte than the length of q, but it can be smaller.

•S is the big-endian signed encoding of s (same treatment than for r; note: R and S may have distinct lengths).

•B is a single byte containing the length of R (in bytes).

•C is a single byte containing the length of S (in bytes).

•A is a single byte containing B+C+4 (i.e. the length, in bytes, of what follows the byte A).


Answer

Barry, it's easier for me to add the method as I described before rather than to spend the time to determine whether what you described above is correct or not.

I added a new method: CkDsa::SetEncodedSignatureRS(const char encoing, const char r, const char *s).

If you would like a new build for testing, please let me know. Make sure to tell me all the specifics: operating system, architecture, MSVC++ version (if Microsoft), etc.