{"id":1031,"date":"2014-01-12T18:43:08","date_gmt":"2014-01-12T18:43:08","guid":{"rendered":"http:\/\/warc.org.uk\/?page_id=1031"},"modified":"2014-01-13T15:08:00","modified_gmt":"2014-01-13T15:08:00","slug":"software-product-keys-as-used-in-myvna-by-dave-g8kbb","status":"publish","type":"page","link":"https:\/\/warc.org.uk\/?page_id=1031","title":{"rendered":"Software product keys as used in myVNA by Dave G8KBB"},"content":{"rendered":"<p>As many of the WARC members will know \u2013 because I\u2019ve bored you with talks on the subject \u2013 I have had great fun for several years writing <a href=\"http:\/\/g8kbb.co.uk\/html\/myvna.html\">Vector Network Analyser (VNA) software<\/a> for the most excellent <a href=\"http:\/\/g8kbb.co.uk\/html\/n2pk_vna.html\">N2PK VNA<\/a> by <a href=\"http:\/\/n2pk.com\/\">Paul Kiciak<\/a>. Most people will have heard the talk on VNAs \u2013 if sufficient have not, I\u2019m happy to give another J.<\/p>\n<p>Free for amateur use, there are some commercial applications supported by <a href=\"http:\/\/www.makarov.ca\/vna.htm\">Ivan Makarov VE3IVM<\/a>. In order to protect the investment we\u2019ve made, I agreed to implement some product key protection. As a result, when you first run the program you see this:<\/p>\n<p><a href=\"https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/key-management.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1038\" alt=\"key management\" src=\"https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/key-management.png\" width=\"559\" height=\"334\" srcset=\"https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/key-management.png 559w, https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/key-management-300x179.png 300w, https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/key-management-160x95.png 160w, https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/key-management-250x150.png 250w, https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/key-management-150x89.png 150w\" sizes=\"auto, (max-width: 559px) 100vw, 559px\" \/><\/a><\/p>\n<p>So, how does it work? Well, not as described here. Not exactly anyway \u2013 it\u2019s very similar to this though. I\u2019m not going to say exactly how I implemented it.<\/p>\n<p>In this article, I\u2019ll cover the design, cryptography and implementation.<\/p>\n<h1>Principles<\/h1>\n<p>What is a product key? It\u2019s a string of data that the program will accept as a valid key in order for the program to operate. However it must be constructed in such a way that someone cannot guess a valid key. Easy \u2013 make it structured in such a way that a randomly chosen string will not work. That means that the chance of any random string being tried must be unlikely to work.<\/p>\n<p>One way might be to use a cryptographic hash of a short message. Problem though. If anyone reverse engineers the program and discovers the structure all is lost. So we need something more sophisticated.<\/p>\n<p>How about using an asymmetric cipher? Public key cryptosystems have been the subject of talks at the <a href=\"http:\/\/www.warc.org.uk\/\">Warrington club<\/a> before \u2013 and specifically the <a href=\"http:\/\/en.wikipedia.org\/wiki\/RSA_(algorithm)\">RSA<\/a> cryptosystem. This relies on the fact that factorisation of a large integer that is the product of two large primes is computationally expensive. This would work.<\/p>\n<p>Bit of a problem though. Using something like 1024 bit RSA would mean a product key of 128 bytes \u2013 way too long.<\/p>\n<p>So, that won\u2019t work. I think we\u2019ve not covered it in a lecture at the club yet, but a better choice would be to use Elliptic Curve cryptography. Key lengths are much shorter; for example a 256 bit EC key has roughly the same strength as 3000 bit RSA. A 160 bit curve gives roughly the same security as 1024 bit RSA. Even 160 bits is a bit big but we can reasonably choose a smaller curve given the level of security that we seek. There are many good tutorials on the internet on ECC. <a href=\"http:\/\/en.wikipedia.org\/wiki\/Elliptic_curve_cryptography\">Wiki is good<\/a> and here is a good clear <a href=\"http:\/\/www.embedded.com\/design\/safety-and-security\/4396040\/An-Introduction-to-Elliptic-Curve-Cryptography\">tutorial<\/a>.<\/p>\n<p>There was quite a good write-up of product keys on the internet that I found that taught me a lot, but it had a fundamental problem \u2013 it used <a href=\"http:\/\/en.wikipedia.org\/wiki\/Integrated_Encryption_Scheme\">ECIES<\/a> (er, don\u2019t worry, we\u2019ll explain this a bit later). You can find the write-up <a href=\"http:\/\/www.codeguru.com\/cpp\/cpp\/algorithms\/general\/article.php\/c12799\/Product-Keys-Based-on-Elliptic-Curve-Cryptography.htm\">here.<\/a><\/p>\n<p>My implementation? I used a method called <a href=\"http:\/\/en.wikipedia.org\/wiki\/ECDSA\">ECDSA<\/a> but with a few twists. Those twists I do not present here.<\/p>\n<p>Ok, there are limits. You can always crack the program. It needs to protect itself as far as it can.<\/p>\n<h1>What is an elliptic curve?<\/h1>\n<p>Remember you maths?<\/p>\n<p><a href=\"https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/image002.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" alt=\"image002\" src=\"https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/image002.png\" width=\"113\" height=\"20\" \/><\/a><\/p>\n<p>That\u2019s the equation of one. There are other forms but we\u2019ll use this one.<\/p>\n<p>For certain values of a and b, you might get a curve like this if you plotted it<\/p>\n<p><a href=\"https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/plot-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1034\" alt=\"plot 1\" src=\"https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/plot-1.png\" width=\"409\" height=\"410\" srcset=\"https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/plot-1.png 409w, https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/plot-1-150x150.png 150w, https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/plot-1-300x300.png 300w, https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/plot-1-160x160.png 160w, https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/plot-1-149x150.png 149w\" sizes=\"auto, (max-width: 409px) 100vw, 409px\" \/><\/a><\/p>\n<p>You can take two points on this curve and construct a method for \u201cadding\u201d points like this:<\/p>\n<p><a href=\"https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/plot-2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1035\" alt=\"plot 2\" src=\"https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/plot-2.png\" width=\"300\" height=\"359\" srcset=\"https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/plot-2.png 300w, https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/plot-2-250x300.png 250w, https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/plot-2-133x160.png 133w, https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/plot-2-125x150.png 125w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Adding point P and Q gives point R.<\/p>\n<p>If you add a point to itself (Q = P+P, in other words Q=2P) that\u2019s the equivalent of \u201cdoubling\u201d the point. 2P+P is 3P and so on; we therefore have the notion of \u201cpoint multiplication\u201d.<\/p>\n<p>In RSA we use \u201csquare and multiply\u201d to perform exponentiation. In ECC we use \u201cdouble and add\u201d to perform point multiplication.<\/p>\n<p><a href=\"https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/plot3.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1036\" alt=\"plot3\" src=\"https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/plot3.png\" width=\"300\" height=\"395\" srcset=\"https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/plot3.png 300w, https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/plot3-227x300.png 227w, https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/plot3-121x160.png 121w, https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/plot3-113x150.png 113w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>So how do we do this in cryptography?<\/p>\n<p>Well, we use a variant where we have integer points on the curve rather than using real numbers, and we construct it in such a way that the points we use form a <a href=\"http:\/\/en.wikipedia.org\/wiki\/Finite_field\">finite field<\/a>. That\u2019s as far as we\u2019ll go for now on the number theory \u2013 oh and to make the maths work we also need to define the \u201cpoint at infinity\u201d.<\/p>\n<p>We\u2019ll use a prime field here but there are other forms. This means that all calculations are performed modulo a prime p.<\/p>\n<p>So what does a point look like? Well, it has an X and a Y coordinate. It is a point on a curve.<\/p>\n<p>And the formula for point addition? A bit messy.<\/p>\n<p>If you have two points X1 and X2 we can add them together to form a point X3 as follows, where x<sub>1<\/sub>,y<sub>1<\/sub> are the x and y coordinates of point X1 etc.<\/p>\n<p>Notice the convention? Points have x and y coordinates and are represented in upper case.<\/p>\n<p>So, we add X1 and X2 as follows (this is the case when the points have different x coordinates \u2013 there is a different rule for the other case).<\/p>\n<p>First calculate \u03bb as follows<\/p>\n<p><a href=\"https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/image006.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" alt=\"image006\" src=\"https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/image006.png\" width=\"135\" height=\"40\" \/><\/a><\/p>\n<p>Then calculate<\/p>\n<p><a href=\"https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/image007.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1041\" alt=\"image007\" src=\"https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/image007.png\" width=\"177\" height=\"20\" srcset=\"https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/image007.png 177w, https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/image007-160x18.png 160w, https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/image007-150x16.png 150w\" sizes=\"auto, (max-width: 177px) 100vw, 177px\" \/><\/a><\/p>\n<p><a href=\"https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/image008.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1042\" alt=\"image008\" src=\"https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/image008.png\" width=\"197\" height=\"20\" srcset=\"https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/image008.png 197w, https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/image008-160x16.png 160w, https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/image008-150x15.png 150w\" sizes=\"auto, (max-width: 197px) 100vw, 197px\" \/><\/a><\/p>\n<p>Fortunately we don\u2019t have to muck about with all this as there are libraries freely available to do it.<\/p>\n<p>So we have a curve. It has values a and b (remember that equation above?). It has a prime number p. It also has a couple of other numbers. One is called the \u201cbase point\u201d or generator. The other is the \u201corder of the base point\u201d.<\/p>\n<p>What are these?<\/p>\n<p>The base point (G) is a point on the curve. If you add it to itself, you get another point on the curve. That is 2G. Add the basepoint again. 3G. Keep going. Eventually you get back to where you started. That should happen after a lot of operations; ideally, for a 160 bit curve, it should be pretty close to after 2<sup>160<\/sup> operations. How many times exactly? That\u2019s the \u201corder\u201d of the base point.<\/p>\n<p>So we have our maths. We have a curve. We can do basic mathematical operations because they form a finite field.<\/p>\n<h1>Digital Signatures<\/h1>\n<p>The product keys I implemented are a form of digital signature known as the Elliptic Curve Digital Signature Algorithm (EC-DSA).<\/p>\n<p>To use it, first generate a private key. This is just a randomly chosen integer less than the order of the basepoint (let\u2019s call it d). The public key is a point on the curve (P) that is generated by multiplying the base point by d; in other words P = d*G. Note the convention again; P and G are points, d is an integer. \u2018*\u2019 is point multiplication.<\/p>\n<p>Now, suppose you want to sign a message m.<\/p>\n<p>Follow these steps:<\/p>\n<ol>\n<li>Calculate a hash of the message e = hash(m) and truncate if needed<\/li>\n<li>Select a random number k less than\u00a0 the order of the basepoint<\/li>\n<li>Calculate the point on the curve (x<sub>1<\/sub>, y<sub>1<\/sub>) = k * G<\/li>\n<li>Calculate r = x<sub>1<\/sub> mod p. If r is zero, go back to step 2<\/li>\n<li>Calculate s = k<sup>-1<\/sup>(e + rd) mod p. If s is zero, go back to step 2<\/li>\n<\/ol>\n<p>The signature is the pair (r,s). This is what I do to create a product key.<\/p>\n<p>The VNA program does this to verify a signature (P is the public key that corresponds to d):<\/p>\n<ol>\n<li>Check that r and s are integers between 1 and the order of the basepoint<\/li>\n<li>Calculate e = hash(m) and truncate if needed<\/li>\n<li>Calculate w = s<sup>-1<\/sup> mod p<\/li>\n<li>Calculate u<sub>1<\/sub> = ew mod p and u<sub>2<\/sub> = rw mod p<\/li>\n<li>Calculate the curve point (x<sub>1<\/sub>,y<sub>1<\/sub>) = u<sub>1<\/sub> * G + u<sub>2<\/sub> * P<\/li>\n<li>The signature is valid if\u00a0 r\u00a0 = x<sub>1<\/sub> mod p<\/li>\n<\/ol>\n<p>Don\u2019t need to code this either as again there are libraries to do it. What I did need to do however was this:<\/p>\n<ol>\n<li>Make a program to generate EC keys and using those keys product keys<\/li>\n<li>Modify the VNA program to require product keys<\/li>\n<li>Modify the VNA program to generate activation data and require an activation key<\/li>\n<li>Make a program to generate activation keys<\/li>\n<\/ol>\n<p>And because I need to be able to generate activation keys for people on demand<\/p>\n<ol>\n<li>Port the activation key program to my phone as an android app<\/li>\n<\/ol>\n<h1>So what are my product keys?<\/h1>\n<p>Take a short message m. That message is a couple of bytes that define the permissions granted by the product key \u2013 for example it might be to permit the program to be used for a period of time, or for a limited range of features. The program is going to interpret this message. The message is signed using EC-DSA. The product key is just the concatenation of m,r,s.<\/p>\n<h1>How does this differ from the ECIES mentioned earlier?<\/h1>\n<p>ECIES is an encryption program. Given a public key P, I can create a message that only the person that knows the private key d can read. If you used this for a product key, the private key d would need to be known by the VNA program \u2013 and the program is the thing that you distribute. Reverse engineer it and all is lost \u2013 the adversary knows the secret.<\/p>\n<p>ECDSA is the other way round. To sign a message you use the private key d. The program that interprets the signature only needs to know the public key P.<\/p>\n<h1>Is that all there is to it?<\/h1>\n<p>Well, no.<\/p>\n<p>Here is one of my product keys.<\/p>\n<p style=\"text-align: center;\">58BWK-43Y4Y-YK8SI-YK5EI-EA8V6-T4NIR-KBR64<\/p>\n<p>Here is another<\/p>\n<p style=\"text-align: center;\">NB4KQ-FQB8J-PR5D3-XNSVW-C7AFU-2T48N-QKQER<\/p>\n<p>These are signatures of the same message. It\u2019s an evaluation key by the way, so won\u2019t be of much use. So if the message is the same, why do the first few characters differ? That\u2019s because amongst other things there is an additional layer of obfuscation added. It has been transformed by a symmetric cipher. This is just for the hell of it. An additional layer to make the hacker\u2019s job a bit harder.<\/p>\n<p>Incidentally, why does it look like it does? A series of 5 letter groups with alphanumeric characters. It\u2019s called \u201cBase 32\u201d coding and is grouped if 5s to make entry easier. The binary data of the signature, m,r,s, is split into groups of 5 bits and each group of 5 bits is coded as one of 32 characters which comprise the letters in upper case and the numbers. That means 36 possible codings but we only need 32, so 4 are omitted. These are the 4 that may cause confusion 0 vs O for example.<\/p>\n<p>One final twist. The final character is a checksum. It is a simple mechanism to try to avoid typing errors if someone types in the key manually to myVNA.<\/p>\n<h1>Is THAT all?<\/h1>\n<p>Nope.<\/p>\n<p>So, I supply a product key. What happens if someone publishes one on the internet? Game over as it works for everyone.<\/p>\n<p>So we need a second level. It needs to be associated with a specific instance of a PC. The way this works is as follows. We read a set of identifiers for a PC \u2013 its software version, the CPU type, the amount of RAM, the type of hard drive, the MAC address of network interfaces etc. These are hashed together to generate a fingerprint of the PC.<\/p>\n<p>That signature is returned to me as \u201cactivation data\u201d. I generate a second \u201cactivation key\u201d which is another EC-DSA signature on the concatenation of the product key and the activation data. That is entered into the PC to \u201cactivate\u201d it.<\/p>\n<p>The activation data is a constructed data item of several fields.<\/p>\n<p>The first 8 bytes of the activation data is a MAC of the product key. A MAC \u2013 Message Authentication Code \u2013 is a keyed cryptographic hash of a message. It may be calculated in many different ways \u2013 <a href=\"http:\/\/en.wikipedia.org\/wiki\/CBC-MAC\">CBC-MAC<\/a>, <a href=\"http:\/\/en.wikipedia.org\/wiki\/Cmac\">CMAC<\/a>, etc. Pick any suitable method using any reasonable block cipher. There are also hash based algorithms that may be used such as <a href=\"http:\/\/en.wikipedia.org\/wiki\/Hmac\">HMAC<\/a>.<\/p>\n<p>The second 8 bytes is another MAC \u2013 this time of the MAC of the product key and the identities of the PC signature components. In hindsight I wish I had reversed the order of the two 8 byte subfields \u2013 people tend to look at the start of the activation data and assume that two strings are the same when the second half is totally different.<\/p>\n<p>It is also a pain to have to change the activation key when small changes are made to the hardware, so the program implements a set of weighting factors on the sub-elements. This allows scope for changes to the PC but a complete change \u2013 such as copying the data to a different PC \u2013 gets caught.<\/p>\n<h1>And is that secure?<\/h1>\n<p>Not completely. There are ways around this lot, but they take effort. It serves its purpose \u2013 it applies a reasonable barrier.<\/p>\n<h1>What\u2019s the code look like?<\/h1>\n<p>Here is the interface to the program I wrote to generate product and activation keys. It also supports the generation of a private and public key for both signature types. For various types of licence it will generate product keys, and for a given product key and activation data it will generate an activation key.<br \/>\n<a href=\"https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/image009.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" alt=\"image009\" src=\"https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/image009.png\" width=\"495\" height=\"514\" \/><\/a><\/p>\n<p>The Android version just generates activation keys.<\/p>\n<p><a href=\"https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/android-key-gen.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1037 aligncenter\" alt=\"android key gen\" src=\"https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/android-key-gen.png\" width=\"966\" height=\"892\" srcset=\"https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/android-key-gen.png 966w, https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/android-key-gen-300x277.png 300w, https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/android-key-gen-160x147.png 160w, https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/android-key-gen-162x150.png 162w, https:\/\/warc.org.uk\/wp-content\/uploads\/2014\/01\/android-key-gen-150x138.png 150w\" sizes=\"auto, (max-width: 966px) 100vw, 966px\" \/><\/a><\/p>\n<p>Most of it is basic windows\/android code. The interesting crypto bits look like this\u2026.<\/p>\n<p>The library to use is the wonderful <a href=\"http:\/\/www.cryptopp.com\/\">crypto++<\/a>. It provides primitives for ECDSA.<\/p>\n<p>Assuming that p is the prime factor, a and b are the constants for the curve, n is the order of the subgroup and x and y are the coordinates of the base point we define the curve and private &amp; public components thus, where sk is the value of the private key:<\/p>\n<p>CryptoPP::ECP ec( p, a, b );<\/p>\n<p>&nbsp;<\/p>\n<p>CryptoPP::ECDSA&lt;CryptoPP::ECP, CryptoPP::SHA1&gt;::PrivateKey PrivateKey;<\/p>\n<p>CryptoPP::ECDSA&lt;CryptoPP::ECP, CryptoPP::SHA1&gt;::PublicKey PublicKey;<\/p>\n<p><span style=\"color: #339966;\">\/\/ Curve Initialization<\/span><\/p>\n<p>PrivateKey.Initialize( ec, CryptoPP::ECP::Point( x, y ), n, sk );<\/p>\n<p>PrivateKey.MakePublicKey( PublicKey );<\/p>\n<p><span style=\"color: #339966;\">\/\/ create a signer and verifier<\/span><\/p>\n<p>CryptoPP::ECDSA&lt;CryptoPP::ECP, CryptoPP::SHA1&gt;::Signer Signer( PrivateKey );<\/p>\n<p>CryptoPP::ECDSA&lt;CryptoPP::ECP, CryptoPP::SHA1&gt;::Verifier Verifier( PublicKey );<\/p>\n<p>&nbsp;<\/p>\n<p>The keys are validated thus<\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #0000ff;\">if( false<\/span> == PrivateKey.Validate( rng, 3 ) )<\/p>\n<p>{ <span style=\"color: #0000ff;\">throw<\/span> CString(_T(&#8220;Private Key Validation&#8221; )); }<\/p>\n<p><span style=\"color: #0000ff;\">if( false<\/span> == PublicKey.Validate( rng, 3 ) )<\/p>\n<p>{<span style=\"color: #0000ff;\"> throw<\/span> CString(_T(&#8220;Public Key Validation&#8221; )); }<\/p>\n<p>&nbsp;<\/p>\n<p>Signing a message is done using the Signer:<\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #339966;\">\/\/ allocate space for signature<\/span><\/p>\n<p>size_t siglen = Signer.MaxSignatureLength();<\/p>\n<p>std::string signature(siglen, 0x00);<\/p>\n<p><span style=\"color: #339966;\">\/\/ sign<\/span><\/p>\n<p>Signer.SignMessage( rng, (byte *)&amp;Message, MessageLen, (byte*)signature.data() );<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>And so on.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>As many of the WARC members will know \u2013 because I\u2019ve bored you with talks on the subject \u2013 I have had great fun for several years writing Vector Network Analyser (VNA) software for the most excellent N2PK VNA by Paul Kiciak. Most people will have heard the talk on\u2026<\/p>\n<p class=\"continue-reading-button\"> <a class=\"continue-reading-link\" href=\"https:\/\/warc.org.uk\/?page_id=1031\">Continue reading<i class=\"crycon-right-dir\"><\/i><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"parent":34,"menu_order":0,"comment_status":"open","ping_status":"open","template":"templates\/template-page-with-intro.php","meta":{"footnotes":""},"class_list":["post-1031","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/warc.org.uk\/index.php?rest_route=\/wp\/v2\/pages\/1031","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/warc.org.uk\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/warc.org.uk\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/warc.org.uk\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/warc.org.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1031"}],"version-history":[{"count":5,"href":"https:\/\/warc.org.uk\/index.php?rest_route=\/wp\/v2\/pages\/1031\/revisions"}],"predecessor-version":[{"id":1063,"href":"https:\/\/warc.org.uk\/index.php?rest_route=\/wp\/v2\/pages\/1031\/revisions\/1063"}],"up":[{"embeddable":true,"href":"https:\/\/warc.org.uk\/index.php?rest_route=\/wp\/v2\/pages\/34"}],"wp:attachment":[{"href":"https:\/\/warc.org.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1031"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}