A blind signature allows Bob to hide the content of a message before it is signed by a trusted entity (the signer). This is typically used when the creator of a message is different to the entity which signs it. For example, Bob may blind the message (such as his vote), and then for Trent to sign it as being valid, but where Trent will not know the contents of the message (or his vote). In this case we will use the CIRCL library from Cloudflare to implement a blind RSA signature for RSA-1024 (not secure) and RSA-2048, and use metadata to produce a partially blinded signature, and where the blind signature can see the metadata. Thus Trent will see the metadata, but not the message when he is creating a blind signature.
Partially Blinded RSA Signature using CIRCL |
Method
A blind signature allows Bob to hide the content of a message before it is signed by a trusted entity (the signer). This is typically used when the creator of a message is different to the entity which signs it. For example, Bob may blind the message (such as his vote), and then for Trent to sign it as being valid, but where Trent will not know the contents of the message (or his vote). This could thus be applied to voting systems, and where Bob registers his vote, and Trent then signs it as being a valid vote cast (using Trent's signing key). Bob can then get this back, and unblind his message, and then cast the vote. The vote will thus contain Bob's message, but be signed by Trent.
In traditional RSA, we sign with:
\(Sig=M^d \pmod N\)
and where \(N\) is the modulus, and \(d\) is the decryption exponent. In a blinded version, we generate a random value of \(r\) and which is relatively prime to N (\(gcd(r, N) = 1)\)). We then compute:
\(m'=m.r^e\)
The value of \(m'\) is then sent to the signing authority (Trent). The signing authority then computes the blinded signature as:
\(s'=(m')^d \pmod N\)
This is then sent back to the creator of the message, and who can then sign with:
\(s=(s').r^{-1} \pmod N\)
This will remove the blinding factor, and now be signed by the signing authority, but will not reveal the message to them. Overall this will work because:
\(s=(s').r^{-1} = (m')^d.r^{-1} = (m.r^e)^d.r^{-1} = m^d.r^{ed}.r^{-1} = m^d.r.r^{-1} = m^d \pmod N\)
Thus we have a signature which is signed by Trent's decryption key (\(d\)), and with the message of Bob (\(m\)).
Coding
In the code (to save processing time) we have integrated static RSA keys, and then load up the verfier ad the signer with the blinded message and etadata::
key := loadStrongRSAKey(size) verifier := partiallyblindrsa.NewVerifier(&key.PublicKey, crypto.SHA512) signer, _ := partiallyblindrsa.NewSigner(key, crypto.SHA512) blindedMsg, _, _ := verifier.Blind(rand.Reader, message, metadata) blindedSig, _ := signer.BlindSign(blindedMsg, metadata)
The protocol is thus:
Client(pk, msg, info) Server(sk, pk, info) ------------------------------------------------------- input_msg = Prepare(msg) blinded_msg, inv = Blind(pk, input_msg, info) blinded_msg ----------> blind_sig = BlindSign(sk, blinded_msg, info) blind_sig <---------- sig=Finalize(pk, input_msg, info, blind_sig, inv)
We can use the CIRCL library from Cloudflare to implement:
package main import ( "crypto" "crypto/rand" "crypto/rsa" "crypto/x509" "encoding/hex" "encoding/pem" "fmt" "math/big" "os" "strconv" "github.com/cloudflare/circl/blindsign/blindrsa/partiallyblindrsa" ) func ExportPublicKeyAsPemStr(pubkey *rsa.PublicKey) string { pubkey_pem := string(pem.EncodeToMemory(&pem.Block{Type: "RSA PUBLIC KEY", Bytes: x509.MarshalPKCS1PublicKey(pubkey)})) return pubkey_pem } func ExportPrivateKeyAsPemStr(privatekey *rsa.PrivateKey) string { privatekey_pem := string(pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privatekey)})) return privatekey_pem } func loadStrongRSAKey(size int) *rsa.PrivateKey { pVal := "c93518f3695c19c3d742b43e12da4eb86d49d92cadaf3cbf42f2498a4cb0605f3c48c2779c0232869cf2e66bcb498818c9aaaa7c6527394808f2f24c0318d304e235faf1ad9c82e03a62d0999118dc9344adbb05abb8208e60faafdbac7f76a7cae7b8c576cdb960806fa59b4026bfcb96c1e8356c042e4c2e228b1560a8caaf" qVal := "a8de748c1efe578b4459e07d94688efef70330670291821f0273f035e9d8ce86094c1b2a16aeb36be391a24bf5f850c8f3a3d3fd406acb6a41aa622d66fe1f4550193c3a50081e9c44b61ae12e14f2f1a466299f77c74a1e6b61b3c2404087d4533b37309cca11e92d772ad6009e61821aef33e92d3578df50592e95073e79d7" Nval := "84b9b00590ede00c00069eab7faa638ce63928ed06b7c3c24a3bfee4425bab0323c35bcc4a7a291dd3ff1496b01a2c1b69074dc617fddf1dcd4943b417e398567f2cdc5476c1a57bfa98f6f80ed4712e4d12b45c8af8bfe555ec7c1f159bc7414921ab6fca9483696b98f5171dbffe6750de38ef0364da698c16a36267a94935ec4aa3a06517ec47973c572c9b0d0baa4c8fb35f1de19c19abd5343e17cdc6bc89a794c592c82ea10964252d044e94ef9a6a0adb57a1f4005ff8fbee09febf1de809c41aab88594e8ebb1ded26686286967816ab953a3399a427278fc80a545290eaa777756a87eb35141deb4634db4f043d3515201cbd3a151259ead4f0eff9" eVal := "010001" dVal := "2e67c6158c20bf8f328b1dfb147dfca48cf23b4ef46457fb9c7cf197d963b79d3769dcb4c6ed8366bc72993e3e80481fa54f3a70227f4efd5a835d3aa087a101cd21603fdfedc0f062240d6599b9c980c8cddb65e7e9251f0835d10805441c1cc577123bd9f6a723bacd1614690071f0a9a3a900588d70982ab4d797566b27ff4323f386b5e742119317bea2437ad329f4ef29f2c877d0222ea46acc8c70b12e40ccd25fa6c03d5758dfe61251c9280f28d9b2f18d9268b7425c7366216aa880f52f2e8b5d1d1b6e44ad0f3a54c17418c8091a3c8a9326213929d9ecbc217775ad580adf1fd6d0c1214443ac802e1a38d025cfac9268df93662f7004569b64e9" if size == 512 { // Note used ... too small pVal = "dde950a7c628880b3c4795b7e9045ecb238db761c138ca277786ee5373ca7d73ac6f5c66ba6089e3e74d35bda7479e4c56e37fd7333a21183360a2465ac0f60f" qVal = "9eaf5f8eece5c56825815659237ab60054c16d74493184cec6f24fbf164c120a3e3e18a4e2b761af9bbdce530a2ac890fc4bb847b76f207f95dc7e27606a8f7f" Nval = "898e051b28b0bc7386f85a5623b97df3500dd3284ed0ed2793496efa0799164dbed2d5c0c485e4727c3fc57f197bab462e16a16815ad4574e181a7c20dc6cba22170f7ce6d3b5634d41f3d95c04c3dc0e3c647a75d3b8e62108e9501359d53800395f53583c1d1a4f8c7d82d134abf03b1cd994a02790a7007249c0d51627271" eVal = "010001" dVal = "696b303a9a3aa8929953e857afd54ed393fca46175d5e48ab9f4435ad74bd9ae079aa93aace2382c0d510a58d7fcd14c5db1f64d409fa4656915e6ad6fc574f54ea07a6dabbf2bc0a591c5b3bfe0718d74a8bf4451061066df807f3936b777ac6bce73baa90e7845d547bbff6c75534944a678ad7ff83c628d3ec49d8f8fd489" } if size == 1538 { pVal = "fd535ecd8b03af558b56d9fc9858e77f0f5b7345af095a85c00879002d77410d7a0cfdf18114a7ed0ce4a87673ab212054193e7c2b763d586a65a9310de4f10209bf278b5dbfe2d1cfd71241d853f1b3b83834f465c9a0b71726d4713c660246dda7e977576a1b3bb33d86a4a31391aa1e81c7a90ca1bf5b01a6d1e3c4c1064f5fe4e6271140d002190b1990d22dc28f76f3cca7d4f08e26f6a2498b9dafe7de3ba95569903e55f6d7d7b41848c891427e2bcf7b3f7e4071565b9168a6b50db3" qVal = "e3ab548392c0de2cb00187fc893385d0c8e0b2450d70d352aacf2160aef8018299ffc458f0980d4d96d7afaab7b4f30a3a1b7313c9a48d8011c4682a22ab35d6eb7acb5cb048016ed7fa9ce243dc808de7a5e65abe3d20ebf9db887cc2b460318b99b69d2c70f50a9c9d73ec07bc00454f0fe04d815643c09006dd35b9b94f5d49133debfaecff43f8db3cfe0a11378bb4c368a525020f6d90aec36ca882b284e778ed781f166bf1c401f758fb2e9f1a2cf26af32931e1a70752080ba64abb67" Nval = "e14a7762238d7b2d29429c824f4bc5db5391e6b1e679381a9aa990246539189a3380be9ffd5b238d8f73c4f07d87a1fa91b1dd3404b766ae0da76cbc82bd2a5901eb390bd36123e3a301a8fafcb0f2c8a6aaceba85cbfc4bac26f5f274503b2f89476ea77516be96a9570997935a92fa483275c8e2b97aa3c8ea640490b1a13fff8f1ed71d1ba03b035300968d4563499d7e896595c1622a376bbdeb30bd5b6b38fff0b49923f2b4ca106609279f65318067346ec00e68836f37bda3f983807fe1c2299c98d30a3f283f9a67fcbba8e61f1187e5cb94da16c8523bbbb98d93317d8c807a4ba4cc1ce60c8cb833ed0b91f2b8fd623d89c3ddba473ee90ae72c36948a2fcd6d43f6431d36084efea3c37e9ee785c8b3905bcd0d0fd99ae2255415c864348745ade51f525fe9372d4cac0238646bcba4cc53b8e6513c0ca7b148556163690af316177f888a73641cad017ed10efe5371cabcd79b3844eca5f82d5e25bee9fb0a77b1eea2af65dc10b5ee4d681810ac11992f48a0f3b8ca5b984405" eVal = "010001" dVal = "3014163a29602e234b24de05a92a8084f7e6b116d21a987085051eafc5b2539fc4d1fadc65d32759347dfe4f5c5aafa4aba70b8fe859c35deda8073a8ba416ff7bbb59273eeb021fb84fc86217bf2370d2b0ad017d40350d6925bf6308937eadfc5bf42f647b801ce2f2a22768d8f178dc2378a3704f28eeff179654ab145d572d10bc0228421705c105dba04571c3689865c2a89d36f1de1489b7b41368b5b3c22c4c901e065feb591bfaca855c2cda4d8eb8cfd1c8c1611b410805906011f1d1f3e4b0e3080a72bf13f125273d8337e4d1f0f581d9ad5c79d28bd0ba5397dd7a883a6c37d60bfc292eb8aa6ab6baada3f3dfc27696c829e8418dd132015431d0a7ecf6fe45f189f8c77b87fd5fa2bca3a8bcc248719326d695823fdb0c20d7f6cf88629d1e8331f4a9adcc77187f91f71ad7940815334700230f176d7a3e7ae7306d3d82579be237817a6dc01c3b1376dbaf18e4468915658ff88efc494bbea9a608bb0e89fc332d0e3b844341898370b0d899bc0c503636852676d5129159" } if size == 2048 { pVal = "a97a899b9a5d430ab480e492e45e8066187c45429e5ad17583870a7f3d5ef7b58c471e8dd3ab2bf40fecad3dbeeb2a2679cecd382d281e54f9c1e7edc3710edd010d42e947fe2ad51f58ef2e19ea66da582e24754ad0358c1d455c7066d70eb7bc987807255439d55705f3edca88118e4ce9f2e8487966f7cdc41a13010d4acd0ca5f3d7170df3921861d16b560d3732f112adfe753cc9414ddb0eb15e0da18455f760b156f8ec56a2323b8cc66fb87a0f135f4c1b1381663f321af9844fc961f28687cfd005b5bb7fc20a2a9dc0fdeade251518198c84bd26530bf01a2d327aa1c3806bbd38a0c2232d758a77aa9ca986bf95636a997d20df0a0548c7040813" qVal = "f993f537113e64eeff25deb5212fe12684b41a3236e116cf9e293122f1de5445f48dbbd2b9ff689d540a207dbc5c2a6083d567d992f5b86e9a6536d598970f971ddc07faac7d7efaefdbebc3e92106b100f0eb4ef857d4b6a5a53975f16237f363ea021f4780b84ef115bc5a70243b3d2be937f961fbbcc91e7e16c045691cb9c4eb7f4d3f6d0ec13360fa615a679c0aaa3e5e5ae6a5dfa90d2278609d085e56fd0c579ccc035b546e54c3e54893cf409637cc3bf155fe798927923120aa63d90c2baf998829847d479963dbb35d119d992c19ccf01183e3bcf7f342d76311e262e5ff2c52e99528249b47893feefba770ff75de12c6b295adab628223fed547" Nval = "a53a238c17ee468f1370169a3594748db35bd1acdbecbfc6b0eb5c8d21573482313c23b541381d4c0f9a32ba8b4012210c5a7099098298b5e28c3f22744b457b0b35ec4d9559200433a748857a3eca40f7bbf9a882b115c1ba162921bb99b6ae94f474dae0508c762f59aef39a7e28e82f5986fdce01440c6daa20f12ecc149ffc9451e13a8bc98117af5a9b2bcb2f73eca4bb455c0b89843f4cb850e35e182d5560a2409fcdb5fdfae84721470bfa1b26988691ccd704a2705006f245ae09fa08da63cfb4ebb23ed9729b41680171732909e3ef7390dc08f13345ccee0adea2e0ce5417bd642057c48ddcc752ea2bf9667c6b66d277d7c79745274d16d8f00419a8165f5093f46a2fe7069058e52f6547f2fef4fafd6c7af04095ca76a45ca7a7b0afdd7008e108ea3a5f6382e21bdde2b413bd3913c2c6dd5a9bd13d6fe7f021425dc0ec9ac6fad541b18d76b4a1fb293ae7f05a540ad7c159fec1b236687ef758ce8222bfafb868252be1bd0e9d22f9b66d3889bf63ca027b895153e99d67b9c5f69b7fc916ba1f8db168f878213779dea4abae765cfac0fe03da84ebec2ec8fc7fd1c5e259048bc1773f10904999a26ea859f14f4b65e0fef528da4a5270dbcb377a5800ffdf2ff7e5cea2e09b322735aa32a1f167673d9b0dfe771620bd543acabcf8ff4c4888b29a006a88e05e0b125ae6f1a8d5b53a6c678628b00c45" eVal = "010001" dVal = "4db6b7cb87e1f9ec07df7bb212ab7ddabc56de9b2862059dc5cf1e1bff678dfa02805fe73c02d1bcd9c5d4406b88ba3e331a42c5a87475b16f1a3a03d1a129d002e8dcf96cda9bb57e3a1b6134ab5de40ae1ae3eb521e7b2d3fce261cc64334990241ee668055adba7cfcdfb245a5c9140dc22233486e1e3da9cdf9bb1402a1f49e4d55253803649f2c2f6a1ef8a450a886ebeea93ad9583cf661d776649f6a333fa1cb6bab33dfb74cd55cf70245101fe38556b346699f6714f22c54742e1cc69e79674b68af9ae980650c205d24ff3338544617700d68d9a2d5c92541066c1436da89df5e5a754c0cd5cdf9fbf26e9ca6b90f4aedfd16d3e58377109e305989302110704fd08af0bb20a33758769909458b03ecd0365550d9055e78616130075d2866a93ea789aeb5ad2a2aed8fd1380efe2f2d215116a463ee27de9dc302794cf22912e5f2c0fd751688b7b6e458ca5dcc2e3920e8f43851d0fbbc46acc436054351f61c44460ec64a96efda5925665f7fe56eff5738312a1ec5e75a30fdf763864f1624b284b692890b0de2a37bde410c3694d0fcdecbc9d5413dac8f4bc18cbe7c3a19606e9088dea95513a4c61bebcb753de0ebb9899f4fb94b4acbaa3c8179f315fb1e1fe304c1006f775c2cd103f2e43c3f6caa80f0882bcf5538de0faebc2e55c65c8c49251ad28e3ccaa1e044df633432b7c6ffa730d7b9b39decd" } if size == 4096 { Nval = "d2f82bb21bc023456699aded01e074fa1927c2e71122c1acf266a0fc8f44b620a5ebe214fd58bdeb4f2a7a1fb8cc30ee3ea78c2d63e370501d649369fdd6abaca20b42cb0d3c74f37690b05dce303308835beb71d573bf3f2f1c5281e1c8758803e407e8fe07ccc85e0de1831ff8ced470e0e5760c4617766c01c14eef5b6eeb8266b01cc52b60a9a2e56c0c0c428f70fb76e3c4b80c3f7ef5a2c146be56eef12115b5b7291d767528233b67714a51e5ae9ad5fe8e0f5fee6b7b683df6c034b167317b08d5692840a8d36c80af7b0cb6003648f9a85cf0ca6efc5b85439cd8eda0fc93a3e2818126eb1d224eaa8221629b2f62973e9d27c75ce42c7a7e7e83a9264fd2715ec9e96bf9f5d5acd2e9f5a3388c248e170ff8586ecac43191f34537be466d1c43ad8909dad9a8a4d9177b8134ef745c707a8cd38571168d2faf8f65a14af0d331f1f78f0becdf422b233987332d07eb1a43dc6e764d1e6423af211860ab828c4a30c88403ef1f1e13bf016cb45d85a9abe748fcc963425e3a972fd4aaf5ebbd9f3bf20122990c7b756eff7ada3e869d45b5399bba7c5791cf87483f44ad7ffafdcda8b66faa3cf118bc813cf6fa8b0066984db1cc53046b45f6d11360f96d7f552412d8fd13d2a5130ac70a6b999626c7510d631b46198926f02993fea59e25c26988cca3dcfa438e29cd7801540d9ae2b1acb3ce1c8d389dfd3945" eVal = "010001" dVal = "894c1f4bd38990aacae1faf202c5abfb53c1afb32750c250a694a9f293deb8d4b886b1e4cd1822c9700509e37925d2364aaa49ad0493f0f5029c00dffae5e965f93370edaa988cd821727a8521f9f64c7508ae4ab00a9b0d28c0bae572263e6f1d711ac0c40a1978d0d521cd6f524270b961739406dadacc23f06478d58760c17e650bfa3d4b44a641b0234817f67d599f1db98fbde3a2b32273206bc4d5d8bd2eb5ed43dd4b225b8e9a973f73d855423006ee7bb2c248c1664bb3049880700a8049107428473e7e0e21423ce17728478e0dc6224c32e8362652afd123b680eaed59535055c9c85ea6a6983c2ff56e7ab8d9f6c4cd68038a5866da9781991e5f18ec711be5ad4a4f95fd2167b72bffbcebd4e223abe80c149ff0e9e2e941907eeec2c723ffd8a3de482883357d6cb2737987cddfbd6dfbbc4202e35f0d875c3d80f4d75f10ed16274b68b8d8bc007c5385325a8826bb10c5a007fb98854a3c87baac69141886b2cd06503f88af748fc232d7d4bee7907813f81231179e4dfdd4314c68ba28740405dcf18523c0aadcf2580f464406a1fb641f2452c4643052fefbebcf7cf27771204d2a090f686c61f47860bfac839adc27b1a40efe7701270d8971602530d1c17942f88982105b653474c7c36ebd70b2329708670cc8cd81e7d3ac5fdda680237674cc3be6b3feaa3ef28852444f69c923fc9a053c60ab88c5" pVal = "dbbefe57ae0d8a9ea1047c0261ba7327ff734021d24a91a81eac036d01f32e71d59e74f0d459b4f6cb2ffec527f658b4f2567f51bd6b5eaeabfd6b0b67ad71afd852d3502e6dcff066a4e6b155d972b03a57be3a4e45b14862f582f0ec03a835efa73ea2fe4d5df2e1ae1e9e547fe026acd8545efc7a6cb9c110c7bdac5880ab42dc3b28f9297785cf762db62a8d45ea692860dccfd98a549a35f0af38723cdd65f67240846aaf0d2576653afc78a9a1ccae1b00a3dd75427ef5dcf893a551b9b824555e10b39b7273b1ceb0f47ec423bc6e8861bbe2aa2d7a6bdf55cb8dcd41fa9ecaac358f2a82ccdebab768db0c7b2e5c1680ac556d0cb652b05425f16c7f" qVal = "f5c67e788b63946d33cbfd7c202b679c25d036362d2f22d2e2b25c384ee2b5ac25540153099927d465e442c932a65e1ac97ecf2588924473e3518e9fecc98bf2883bbd7a20f1b1cb4dfdb130d8c9416c36b2d94d648cb017e95a680feaed55e14076c866a3079253c2b58dbcbdd41f1403f15acf819402487e5dd7179e758b27466ca3dbcc3a267089fb67bbbb6e6e4b9bc22b2e96e4ec0375c489ebf430aa5de8b5bfaa4ae113f6e89aca840fa64e5c506c5b5e2f8791ef812702a9d3a9b312b5e1b82845aa01fdc70b72e38314c1947bf1ad6ce108f6e76c9a728acc4725fc85da6688df23738cf910433d3ab8a63857e13ae7cec92639052235d4aa6ac83b" } p := new(big.Int).SetBytes(hexToBytes(pVal)) q := new(big.Int).SetBytes(hexToBytes(qVal)) N := new(big.Int).SetBytes(hexToBytes(Nval)) e := new(big.Int).SetBytes(hexToBytes(eVal)) d := new(big.Int).SetBytes(hexToBytes(dVal)) primes := make([]*big.Int, 2) primes[0] = p primes[1] = q key := &rsa.PrivateKey{ PublicKey: rsa.PublicKey{ N: N, E: int(e.Int64()), }, D: d, Primes: primes, } return key } func hexToBytes(h string) []byte { b, err := hex.DecodeString(h) if err != nil { panic(err) } return b } func main() { msg := "Hello" md := "Bob's signature" size := 1024 argCount := len(os.Args[1:]) if argCount > 1 { msg = os.Args[2] } if argCount > 0 { size, _ = strconv.Atoi(os.Args[1]) } if argCount > 2 { md = os.Args[3] } metadata := []byte(md) message := []byte(msg) key := loadStrongRSAKey(size) verifier := partiallyblindrsa.NewVerifier(&key.PublicKey, crypto.SHA512) signer, _ := partiallyblindrsa.NewSigner(key, crypto.SHA512) blindedMsg, _, _ := verifier.Blind(rand.Reader, message, metadata) blindedSig, _ := signer.BlindSign(blindedMsg, metadata) fmt.Printf("Message: %s\n", msg) fmt.Printf("Metadata: %s\n\n", md) fmt.Printf("\nNote: Only showing the first 400 characters of Private Key, Message and Signature\n") fmt.Printf("\nPartially Blinded Message: (%d bytes) %+v\n", len(blindedMsg), fmt.Sprintf("%X", blindedMsg)[:400]) fmt.Printf("Partially Blinded Sig: (%d bytes) %+v\n", len(blindedSig), fmt.Sprintf("%X", blindedSig)[:400]) err := verifier.Verify(message, blindedSig, []byte(metadata)) if err != nil { fmt.Printf("\nPartially Signature verified") } else { fmt.Printf("\nPartially Signature failed") } fmt.Printf("\nRSA bits: %d\n\n", size) fmt.Printf("Private key:\n%+v\n", ExportPrivateKeyAsPemStr(key)[:400]) fmt.Printf("\nPublic key:\n%+v\n", ExportPublicKeyAsPemStr(&key.PublicKey)) }
A sample run with RSA-1024:
Message: Bob has been nice this year Metadata: Bob's message to Santa Partially Blinded Message: (256 bytes) 2BEF2EC87292BE6F64690A21005159EC9C10AC874EF7B8AD74437AFAF9383474DAD65EAE052C7EA81C1B5DB55CE0F2EE05230FF20186E03DAA3428C2E604961A8853F1E0DADF5ED356F6AD22D38D292AE37518C74C26FE82A03F1229C9EFE2A4A8D6F95884FECDFDD892C969A05F8F1AEC895ACAD9EE46A4BE536C2C67878FE30FF090F5F840F33063A2ABC259373B1CF426766DD2FBD1DA50D5F6685C2AC76106F52BF6F554F407E732C00C7AD05674C435FB70F95D5C3BCF8077885C7A9EA61F50271B5C0E0FBE Partially Blinded Sig: (256 bytes) 34CA8352564778D1DCC152EC30813E4E211DFABAAFE301093D26BFB0BC8C1B653E84949C1165EF78D6EFB409F1C07116A51F28CE8D4633347201769E2210C287E6291D02B314177ABDDA897276033B5506A78706BE4A19E6B6C92CE246C6D76E3A98979E586264216EB2B13FACE2F9BD44A4F5C8607456FA3E6259F34F7CF285AE384495E93FD2A069E34DC7914A884439757EF63AD8B0C33E576323BAEB086DE9929514C783302A20BCD634450AD35CB33E4255E9E657DAE0A6A98168DF11327A1BCBD471B4D62C Partially Signature verified Note: Only showing the first 400 characters of Private Key, Message and Signature RSA bits: 1024 Private key: -----BEGIN RSA PRIVATE KEY----- MIIEpQIBAAKCAQEAhLmwBZDt4AwABp6rf6pjjOY5KO0Gt8PCSjv+5EJbqwMjw1vM SnopHdP/FJawGiwbaQdNxhf93x3NSUO0F+OYVn8s3FR2waV7+pj2+A7UcS5NErRc ivi/5VXsfB8Vm8dBSSGrb8qUg2lrmPUXHb/+Z1DeOO8DZNppjBajYmepSTXsSqOg ZRfsR5c8VyybDQuqTI+zXx3hnBmr1TQ+F83GvImnlMWSyC6hCWQlLQROlO+aagrb V6H0AF/4++4J/r8d6AnEGquIWU6Oux3tJmhihpZ4FquVOjOZpCcnj8gKVFKQ6qd3 dWqH6zUUHetGNNtPBD01FSAcvToVElnq1PDv+QIDAQA Public key: -----BEGIN RSA PUBLIC KEY----- MIIBCgKCAQEAhLmwBZDt4AwABp6rf6pjjOY5KO0Gt8PCSjv+5EJbqwMjw1vMSnop HdP/FJawGiwbaQdNxhf93x3NSUO0F+OYVn8s3FR2waV7+pj2+A7UcS5NErRcivi/ 5VXsfB8Vm8dBSSGrb8qUg2lrmPUXHb/+Z1DeOO8DZNppjBajYmepSTXsSqOgZRfs R5c8VyybDQuqTI+zXx3hnBmr1TQ+F83GvImnlMWSyC6hCWQlLQROlO+aagrbV6H0 AF/4++4J/r8d6AnEGquIWU6Oux3tJmhihpZ4FquVOjOZpCcnj8gKVFKQ6qd3dWqH 6zUUHetGNNtPBD01FSAcvToVElnq1PDv+QIDAQAB -----END RSA PUBLIC KEY-----
A sample run with RSA-2048:
Message: Bob has been naughty this year Metadata: Bob's message to Santa Partially Blinded Message: (512 bytes) 63E7476BE5D2B43BA0E9BCC7B07DCC1789CE4781294E77F6F51BC35B5CEF56913BE9C6C55587B74DE6FAF985CE1C96BC88DE89418B06C26EDA46AB55FEEA04BC67BBB8CEA305B61D44DC826E1EEFF98CFE1A094ECA4E8195E8F6590745F23FBA600BDAFB3C9C743F4A765E1E7111BABCD28446B59F3003287225B9AEF461C1FA3F7A7B41D8163B55D36A0D71940FE0D9DD0EFBB20A91250CE2B65CC64D4223AE3F36A5C52BE441F7224EBEC8CCBD1F8BE408D084043D33A28308A0D1672BF515D1426104EFBB1A0A Partially Blinded Sig: (512 bytes) 6335D204852B59953808AB21E05533C4EA4940AA3788AE07C3B939972647C37143518D1834B6ECFCD11A7B6BDB14168B639CA170B0CF6AEB4A0CB3A9EFC19B918CE6A1A664302A59F9E77108DFD601A4DACA01DF9870E96BA0207E7B50A168D5378A8E08C6A753FB47E7B2C521BB94303EF141F42BE440569E739A6903DB5C3909A0A6BDD1ECFC3E466A010333A1EAD563BBE7C3387C36560DEE3002E4D92BC78F1CAFB8DF7C87C1609F5C48EAF283B580AE53E0EC236A027E5CCD0B53837F785884C290AD8507B1 Partially Signature verified Note: Only showing the first 400 characters of Private Key, Message and Signature RSA bits: 2048 Private key: -----BEGIN RSA PRIVATE KEY----- MIIJJwIBAAKCAgEApTojjBfuRo8TcBaaNZR0jbNb0azb7L/GsOtcjSFXNIIxPCO1 QTgdTA+aMrqLQBIhDFpwmQmCmLXijD8idEtFews17E2VWSAEM6dIhXo+ykD3u/mo grEVwboWKSG7mbaulPR02uBQjHYvWa7zmn4o6C9Zhv3OAUQMbaog8S7MFJ/8lFHh OovJgRevWpsryy9z7KS7RVwLiYQ/TLhQ414YLVVgokCfzbX9+uhHIUcL+hsmmIaR zNcEonBQBvJFrgn6CNpjz7Trsj7ZcptBaAFxcykJ4+9zkNwI8TNFzO4K3qLgzlQX vWQgV8SN3MdS6iv5ZnxrZtJ318eXRSdNFtjwBBmoFl9 Public key: -----BEGIN RSA PUBLIC KEY----- MIICCgKCAgEApTojjBfuRo8TcBaaNZR0jbNb0azb7L/GsOtcjSFXNIIxPCO1QTgd TA+aMrqLQBIhDFpwmQmCmLXijD8idEtFews17E2VWSAEM6dIhXo+ykD3u/mogrEV wboWKSG7mbaulPR02uBQjHYvWa7zmn4o6C9Zhv3OAUQMbaog8S7MFJ/8lFHhOovJ gRevWpsryy9z7KS7RVwLiYQ/TLhQ414YLVVgokCfzbX9+uhHIUcL+hsmmIaRzNcE onBQBvJFrgn6CNpjz7Trsj7ZcptBaAFxcykJ4+9zkNwI8TNFzO4K3qLgzlQXvWQg V8SN3MdS6iv5ZnxrZtJ318eXRSdNFtjwBBmoFl9Qk/RqL+cGkFjlL2VH8v70+v1s evBAlcp2pFynp7Cv3XAI4QjqOl9jguIb3eK0E705E8LG3Vqb0T1v5/AhQl3A7JrG +tVBsY12tKH7KTrn8FpUCtfBWf7BsjZofvdYzoIiv6+4aCUr4b0OnSL5tm04ib9j ygJ7iVFT6Z1nucX2m3/JFrofjbFo+HghN3nepKuudlz6wP4D2oTr7C7I/H/RxeJZ BIvBdz8QkEmZom6oWfFPS2Xg/vUo2kpScNvLN3pYAP/fL/flzqLgmzInNaoyofFn Zz2bDf53FiC9VDrKvPj/TEiIspoAaojgXgsSWubxqNW1OmxnhiiwDEUCAwEAAQ== -----END RSA PUBLIC KEY-----
and for RSA-4096:
Message: Hello Metadata: Bob's signature Note: Only showing the first 400 characters of Private Key, Message and Signature Partially Blinded Message: (512 bytes) 15348C838595164BC7A58CD3808287F325C622B89CDB95F26FF55BED85BE18045B5A535D8C4C29998EA9F84E2641D51BB8E49E3E4CCB5203B725E6E68487FB8659A20050BD03B7643DE46B0240AA92F5A32812F0A4A2E00B4217D5F8D7E7A2CF83FF7CB139D3442CA72A343DDFAA370F54230B3F17F0372056370C3F6ADF5001767E55C065D896DD6DB678CA833271B0DD7C854D6E1C4C89772B3ACCBEFA1BF3F8E7212E45C924CEC33EC230E4C9821BDC1E4E11ADF50E14735C520E2D50593BD9E976FF81C6BF0A Partially Blinded Sig: (512 bytes) 3F530F24D2DDC0535AA43AF6238867D1BC6B096EC7F5D15780CAA91A3461AF73432855FFBD67AACCB7B188733BFAFA33E863ED158C2260BD4AEE0A1BF53C3D6CC53246379796BAE5367CFBC68A2E4874F7B15B435E6BF13848106B0091727CA9E240A23B81F30151B0A58E436E74079E7D92EEAE9E232FB220A89863B5B208053556B5843C44826A808915B2A58C9732058D2BFE3DA43A7646235B3776A1883AE7119A56C96E23D3F2D67B3D2DC6C4D90921B664D39E1352AD1A8E524AC9134003595748556C5874 Partially Signature verified RSA bits: 4096 Private key: -----BEGIN RSA PRIVATE KEY----- MIIJKQIBAAKCAgEA0vgrshvAI0Vmma3tAeB0+hknwucRIsGs8mag/I9EtiCl6+IU /Vi9608qeh+4zDDuPqeMLWPjcFAdZJNp/darrKILQssNPHTzdpCwXc4wMwiDW+tx 1XO/Py8cUoHhyHWIA+QH6P4HzMheDeGDH/jO1HDg5XYMRhd2bAHBTu9bbuuCZrAc xStgqaLlbAwMQo9w+3bjxLgMP371osFGvlbu8SEVtbcpHXZ1KCM7Z3FKUeWumtX+ jg9f7mt7aD32wDSxZzF7CNVpKECo02yAr3sMtgA2SPmoXPDKbvxbhUOc2O2g/JOj 4oGBJusdIk6qgiFimy9ilz6dJ8dc5Cx6fn6DqSZP0nF Public key: -----BEGIN RSA PUBLIC KEY----- MIICCgKCAgEA0vgrshvAI0Vmma3tAeB0+hknwucRIsGs8mag/I9EtiCl6+IU/Vi9 608qeh+4zDDuPqeMLWPjcFAdZJNp/darrKILQssNPHTzdpCwXc4wMwiDW+tx1XO/ Py8cUoHhyHWIA+QH6P4HzMheDeGDH/jO1HDg5XYMRhd2bAHBTu9bbuuCZrAcxStg qaLlbAwMQo9w+3bjxLgMP371osFGvlbu8SEVtbcpHXZ1KCM7Z3FKUeWumtX+jg9f 7mt7aD32wDSxZzF7CNVpKECo02yAr3sMtgA2SPmoXPDKbvxbhUOc2O2g/JOj4oGB JusdIk6qgiFimy9ilz6dJ8dc5Cx6fn6DqSZP0nFeyelr+fXVrNLp9aM4jCSOFw/4 WG7KxDGR80U3vkZtHEOtiQna2aik2Rd7gTTvdFxweozThXEWjS+vj2WhSvDTMfH3 jwvs30IrIzmHMy0H6xpD3G52TR5kI68hGGCrgoxKMMiEA+8fHhO/AWy0XYWpq+dI /MljQl46ly/UqvXrvZ878gEimQx7dW7/eto+hp1FtTmbunxXkc+HSD9ErX/6/c2o tm+qPPEYvIE89vqLAGaYTbHMUwRrRfbRE2D5bX9VJBLY/RPSpRMKxwprmZYmx1EN YxtGGYkm8CmT/qWeJcJpiMyj3PpDjinNeAFUDZrisayzzhyNOJ39OUUCAwEAAQ== -----END RSA PUBLIC KEY-----