Cloudflare, CIRCL and Blinded RSA Signatures

There are few things better than a new album released by your favouriate band, and for a cryptographer, it’s great when some new…

Photo by Kelly Sikkema on Unsplash

Cloudflare, CIRCL and Blinded RSA Signatures

There are few things better than a new album released by your favouriate band, and for a cryptographer, it’s great when some new cryptographic functions are released within one of your favouriate crypto libraries. And, so, the Cloudflare CIRCL library is one of my favouriates, especially as it is so well matched to the future (and one that respects privacy and fully integrates trust). Within there you will find PQC (Post Quantum Cryptography) and Zero Knowledge Proof (ZKP) methods:

https://asecuritysite.com/circl

In CIRCL v1.3.0 we see four new functions: CPABE (Ciphertext-policy Attribute-Based Encryption), Blind RSA Signatures, Schnorr ZKP and DLEQ ZKP:

We also say a long-term goodbye to SIDH/SIKE (as it was recently cracked in the final round of the NIST PQC competition). I have covered the new Schnorr and DLEQ implementations here:

https://asecuritysite.com/circl/circl_sch

https://asecuritysite.com/circl/circl_dl

And, so, in this article, I will implement RSA Blinded signatures.

Blind Signatures

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 from 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 traditional RSA, we sign with:

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:

The value of m′ is then sent to the signing authority (Trent). The signing authority then computes the blinded signature as:

This is then sent back to the creator of the message, and who can then sign with:

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:

Thus we have a signature which is signed by Trent’s decryption key (d), and with the message of Bob (m).

Coding

We can use the CIRCL library from Cloudflare to implement [here]:

package main

import (
"crypto"
"crypto/rand"
"crypto/rsa"
"fmt"
"github.com/cloudflare/circl/blindsign/blindrsa"
"crypto/x509"
"encoding/pem"
"strconv"
"os"
)

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 main() {


msg:="Hello"
bits := 2048

argCount := len(os.Args[1:])

if argCount > 1 {
msg = os.Args[2]
}
if argCount > 0 {
bits,_ = strconv.Atoi(os.Args[1])
}

message := []byte(msg)


key, _ := rsa.GenerateKey(rand.Reader, bits)

verifier := blindrsa.NewRSAVerifier(&key.PublicKey, crypto.SHA512)

signer := blindrsa.NewRSASigner(key)

blindedMsg, _, _ := verifier.Blind(rand.Reader, message)
blindedSig, _ := signer.BlindSign(blindedMsg)

fmt.Printf("Message: %s\n", msg)
fmt.Printf("RSA bits: %d\n\n", bits)
fmt.Printf("Private key:\n%+v\n", ExportPrivateKeyAsPemStr(key)[:400])
fmt.Printf("\nPublic key:\n%+v\n", ExportPublicKeyAsPemStr(&key.PublicKey))
fmt.Printf("\nBlinded Message: (%d bytes) %+v\n", len(blindedMsg), fmt.Sprintf("%X", blindedMsg)[:400])

fmt.Printf("Blinded Sig: (%d bytes) %+v\n", len(blindedSig),fmt.Sprintf("%X", blindedSig)[:400])

err := verifier.Verify(message, blindedSig)
if err != nil {
fmt.Printf("\nSignature verified")
} else {
fmt.Printf("\nSignature failed")
}

fmt.Printf("\nNote: Only showing the first 400 characters of Private Key, Message and Signature")

}

A sample run with RSA-2048 [here]:

Message: Hello
RSA bits: 2048

Private key:
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA+X+UPYZl8DCe2LpmpFUQa0OUBq033U2heX1ok/vT/QRdN6j7
1CP2VpoAJQyMyexO9fJFmVHIFSUzol3v+fLp+6Dp+apI9Uvj75LTpZsCoDJkNocC
xl5U4sg1JeJguPXQKTgubwpG0vgVhS7DhU2jaaDgaHZtvsCSlz1XHSA5/owy8D5J
37H/XiM6meQiTTCEeJKz3qiyddBwEaYAl5LNl9sTncmSRLy+toDdzBO8UUXUNJ4V
m8UCKeqJQmWmVHuT4E5xIgHzHkm1mOslTSwqLPRuxsnMh8eeFLA2dbDjmgABMdFk
lV50V1cvvo1myNoyVm/XG5Bl06wpOcfA0KzzpQIDAQABAoIBAQCuQNh8D/3qP0rx
+13ssCyDffNIpno56ho5C8macWuhbwbb9P3NMEDAQ1aOibFa5dxQEiFh76hafF0P
raQJYgrhX4WKhc/m4lYT4OxI4XZ4BDnRi4H4obGPolzcVLtQ8v2rjD2B+B93ASWm
mv6bf5n+EAora2tCqqS3VHQfN37JtChoBhsnek5/ODTDW8gDCNDj+B1aAZ2E9rQd
lv0c3SHKGp1Cn9xRt9nmhjSv76z6qGcc5olzYFAvXgewTatRpyu4bK5m/bN8Ujln
mDRwsvC6D/RpEf39F80PXXiWnAT4sctXNocxQSo6Yq8Z01XtC322p4CQW82fp8+f
rqk4+1uBAoGBAP4kD296SPclY7Fg86ZdfMWb8UyUHt2ssD9Bu/slNyab3nuxnD5m
Cs11g74Gb4fjYG87rj1j98zYd2Sm5ndUO4QNoAxMcSakYAAdDw8Sf9Q/MQoNEmPE
xvOSn4Btv8Dxih1W8MoF3KF1AleTR1lSlL2mXbUH6kXObPL6kUGgimCNAoGBAPtS
0xa5UY2X8n+9Pi9MHX9MniywC3ppZVA4cKOu1rRYM2hl5UBxQGKwEF5ESTD+TEtq
pK9KEce4gQqIAN/xZ2I4bPxFPq434mI6dUQbzbqNIsXV5DPnAtiwIw5gazhr+WQb
TC0TDRGHDK/rXcSeEA+2SIusFog1czU4fRMcsNV5AoGAQ8DZXJ79VOZi7acrTe8e
lJA+hGv4zqB7XGHp+8qwKVrktZVkUj5iIuRxeve8RD4aN41xpmxAZBxRuEPGrYmH
VG1NffnjMKoh7eXRXfNQoQU3zbYucOrFH6q3W0XnGUlLyQakqzdk2qaXOUHKg8XA
Yc84rEqv6mxeH2kt0JE8UwECgYBESXHfl8Tn8yRJvxK5aTYOk7Paso672Q1VKbC5
WNUvtVNqh10uEFeNOQeJhYZZkI8MYtKSak7AdIpjYSbTslUD5A8A0JPCZJ7XT8jz
E5bnnFeZZ4+U5qzoUZuE2X/ombXulFgzWxzO6WHyHsKgnM4CZuX5RW3t3pAKIuoh
GkeWCQKBgQDVp7ktkmJFQxDGrgaI+Ct5SGE502/31rvob0kAFLP8VCGXwhon/NFk
bvq8D+xMlCGmORt0RPrMjOQACU4SIMTEJLb8swdddOS+LjSP5+B8j+XbCYN61q33
5uX3/TQfhEKRFSR2CDiM5kReE4x19EUOlMVoYEVN9Cw/FCHU0lCjlQ==
-----END RSA PRIVATE KEY-----


Public key:
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEA+X+UPYZl8DCe2LpmpFUQa0OUBq033U2heX1ok/vT/QRdN6j71CP2
VpoAJQyMyexO9fJFmVHIFSUzol3v+fLp+6Dp+apI9Uvj75LTpZsCoDJkNocCxl5U
4sg1JeJguPXQKTgubwpG0vgVhS7DhU2jaaDgaHZtvsCSlz1XHSA5/owy8D5J37H/
XiM6meQiTTCEeJKz3qiyddBwEaYAl5LNl9sTncmSRLy+toDdzBO8UUXUNJ4Vm8UC
KeqJQmWmVHuT4E5xIgHzHkm1mOslTSwqLPRuxsnMh8eeFLA2dbDjmgABMdFklV50
V1cvvo1myNoyVm/XG5Bl06wpOcfA0KzzpQIDAQAB
-----END RSA PUBLIC KEY-----


Blinded Message: (256 bytes) 59509EB8EB8AE161671AE4B7E516CD378931BF46F7D678612694101520F67FE20795541D33B1D1645593E2F7A6873E64AC4C441DF05B7E89ADEA3AD157D572CC82B78BFCE0087AF8BB6BC799B4AFF130A01E61B9803CD33FFFEBBA00376CDDFA8D18BCF37F976499F7FCE8A810BC7E7A4DEB1B95ECA2E340C7A0745941B6E93F70F21EB40F99FA90F0E9074819C14FC0A4CD6A05982A4A5E5F2B2CD1030DD664AC221B46E7D99BEC6B413B5E769AAABE2E6E9F10F7A786F1E3CA91BDE44059C2E955F01CC8ECB1B967AD6C662B261E180E708734B2A20A14DECBBC7424F2E70152517274B6DC394F10A593067EA28A4931BED6A55F27732317D0F39AF27C9E40
Blinded Sig: (256 bytes) 34B1D3CE9C76D4F572A191038A87A03FDA90A23685CCA22C8FFE139245FB65DDE1C09815132A8F051682B6AD3A6F41E1469F75DEB52E88DA6DF93C911D548306F702F549836E98AB087A4D96B9791A3E75003976B699192EA1154D63613FAE6E8547467CAA760EB1B8ED8609003205C13B530DC1612FD20827C13D6D8C80C5E6B5F93192CB8179E95C9ED03BF4F0B8F39B699C1076C1CAB7158EAA3791EA61A2ED9D4B163CCD7CF5352AE7DC018F9324BF98C0DED33F37F209015E6A69B6F2C7D4A55A90C58D688C73B6CD81C4C43538B74C6E6BDB105A571F310402CD4A3E788FE5C6710B330CF507E1D2232FABB5B7E846332F1513C933764148CBEFA6888A

Note: Only showing the first 400 characters of Private Key, Message and Signature
Signature verified

and for RSA-4096 [here]:

Message: Hello
RSA bits: 4096
Private key:
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

Public key:
-----BEGIN RSA PUBLIC KEY-----
MIICCgKCAgEAvXq162gYwIclIoSYpOsoZfNp7MJ/wyoZVA3ZFsWY32Aj2MoTfUXO
YmmGPraStpJWudtJV7HTJxTEFMe9KUbnZHfNWCnuuuoHIppDIIQhE2rU7LcdC4Ci
VUvY1BHEUcs55MTSFW1yxL2CQxbZvPXxNH/0mVcShjKBtOYjMhRPvwdV7yJ2tGrQ
80d5fPFwiNXUwyZWJbxBj3jLE7g1Lw/OdGaCxfi1OsPrRs+32mXsnG1mKPR+bN6X
hZ80JtuAMc1NIIEYcwcSMnD4msOz9wb++LFTRJc7ZbivHgP6dRenGpSX+NiCJwEX
vvWTiNbslISm/fWFTm3ApKtpltFEXE2EgzPh3KdaViGWkm3usW+pp0BGY4w0JO9j
r452piph67zmGW8RKE14Dn+5azsgjJPAT1gYwdGrWMmZj6hmx7gNWznkOOpyAj8o
L2zJLEJKYUIpoEKT+weW+DtsFCnWMT5F/su84wA4pUDAitHNPXJV7BJsxCKE+gC7
oGbqWvoTr5ptV5iUx6N2vK6tZXuftqbdRIoxReco0gH2tjdqr0y56+FQUkj/WcMy
KQPDqbG2dqDrapN8U4+qImgkTn6mZtcj/liDZhbRrOS3y7B3rqVwe/a5GMWsveyb
L6iHfS7+x8vsm07qCwOGzt1pC4PaIetDkSTAK0BQhr3ToiRIBOAbAu0CAwEAAQ==
-----END RSA PUBLIC KEY-----

Blinded Message: (512 bytes) B1C49A8C28BCDBF5C957CF966528BA055A4CD4A503B69CCCA3E5335AE47312F924EBB0C46FD69A334C635EC416E329A66C7852A80B99431E1898EC30043CE0A6421A59F85CCC8A2A05D15399B0A779E613209F0E0432F3128A1CBC2B885F49BDA0236CAB1BADF927649ABBDC777CE105B0E1B4895CE3A72B93B4411724139E03CB625A65B282087238000B600FD6A344A9BF474CEF238A430A222F0972A19D9FE2C4EDD1A8A35B6BDC83F0D92D573C2143F98FFB13354427BDAC66F76E33B6A1A18A57E2303F5630A0998C31C6FFFE358234A4DE56491EFA3FAA7F3ABCEBE065F4497C9C0CD252A1CCAF92BCC6E8DBF4C7F6E4719D5CC967125E173B53D9F1C235593E20EA3DDD6BADAEA15EAD9473678A34BFBEE1F9902BBECDDF12C26963CDF302C9F83FA04FBB78DF09A36EC17A8BA7D4B772D247865C5E6A0D4875B75DA187961052ECD7A5470A9CD9424D1CB235345F895537F949801A6E13E7AEA8AEC4B729587D28566715D43AE7B915C86FFE981F1F3F1D7FB28B738F56586AD3D5D6F2D04A3539F3A77777625D5D36DD80F3698679F984427B78DBB20CB4D1042992DE711FDA662E11B7DAD52BAC68AB71D4B74161CE0725B6503D10F7C404C798B4CF1F07EEDDF3DFFD5F678FCCA04B9D3A4A73A201B73BACE45CC970A42013B99E0CC7D70C0666002B41DA12FF67910658ACA7D0E0128E33A1C5C3FB146983C703
Blinded Sig: (512 bytes) 44F05258EE128C41675D589763E36FB2B6BEB2CE1E604A25884D1AE7B7A7AB9A04DDCB1673824BF3D11B44445C302B2D25519030D9EABA7C97168D5C280F4073FBB0218709AD12B345073EDA465C9DED1B93C5BED57FFBDBC0912D6743B01C15B12FBAC7EDF1FEB9410AC698FE6ED50FBD06ADB846B32502AD095A5862870B8CA9A8A8B0883BFC71D59B640D6D0923B350886758835A6D7AF2937DB44C4359B35494B5C09ED7F88F832B57678682F2B7611F9CFFFA04CDCC7437032D8947F4FF6346E2C7FA0E20482983C1A77DDA8CC19480A168D1681B8A85267DACAA17F613F95D0AD4EB1E9D284AE0F6D6B804DB8408256074266CF6FCB927AB64DD350C4579EA7868D9A1A4527CC09F1BEA520F3B7DF22BC93AEDFD2BACCC9DAB28086BC42E634C2E687E455A9E45F17535A6963D9E20B789478FCCDEE93F33B44CDD2567D0555F382ECBFCDF8CDD0DE87451E0BF8DC3AE42DAF3D208EC41DE21D7717EB2EA1348129BD265C4920E512898115B130B5EF281E408DC1251DA33618FB2FC782AE3455ED3D178836A53DD198D00ABE204C9A91746BD330B627584E1D5DB30C2CE2EAF1820C85BD94BCAE1A762DD5AF9CDC0E3CE5E2CC88AF13992B94AE10299EA077C5B007FC9F1BE400AC2418BD69B0C58668CCBECB4F29862DE375C491926348546369EF8E1BF36F061B0A71A063B86265C5038CB1EF5E7C04401C366EB33
Note: Only showing the first 400 characters of Private Key, Message and Signature
Signature verified

Conclusions

There are many applications where we need blind signatures, including where Bob trusts Trent to sign a document for him, but where Trent cannot see the contents of the document. There are more CIRCL examples here:

https://asecuritysite.com/circl