github.com/cloudflare/circl@v1.5.0/blindsign/blindrsa/brsa.go (about) 1 // Package blindrsa implements the RSA Blind Signature Protocol as defined in [RFC9474]. 2 // 3 // The RSA Blind Signature protocol, and its variant RSABSSA 4 // (RSA Blind Signature Scheme with Appendix) is a two-party protocol 5 // between a Client and Server where they interact to compute 6 // 7 // sig = Sign(sk, input_msg), 8 // 9 // where `input_msg = Prepare(msg)` is a prepared version of a private 10 // message `msg` provided by the Client, and `sk` is the private signing 11 // key provided by the server. 12 // 13 // # Supported Variants 14 // 15 // This package is compliant with the [RFC-9474] document 16 // and supports the following variants: 17 // - RSABSSA-SHA384-PSS-Deterministic 18 // - RSABSSA-SHA384-PSSZERO-Deterministic 19 // - RSABSSA-SHA384-PSS-Randomized 20 // - RSABSSA-SHA384-PSSZERO-Randomized 21 // 22 // [RFC-9474]: https://www.rfc-editor.org/info/rfc9474 23 package blindrsa 24 25 import ( 26 "crypto" 27 "crypto/rand" 28 "crypto/rsa" 29 "io" 30 "math/big" 31 32 "github.com/cloudflare/circl/blindsign/blindrsa/internal/common" 33 "github.com/cloudflare/circl/blindsign/blindrsa/internal/keys" 34 ) 35 36 type Variant int 37 38 const ( 39 SHA384PSSRandomized Variant = iota // RSABSSA-SHA384_PSS_Randomized 40 SHA384PSSZeroRandomized // RSABSSA-SHA384_PSSZero_Randomized 41 SHA384PSSDeterministic // RSABSSA-SHA384_PSS_Deterministic 42 SHA384PSSZeroDeterministic // RSABSSA-SHA384_PSSZero_Deterministic 43 ) 44 45 func (v Variant) String() string { 46 switch v { 47 case SHA384PSSRandomized: 48 return "RSABSSA-SHA384-PSS-Randomized" 49 case SHA384PSSZeroRandomized: 50 return "RSABSSA-SHA384-PSSZero-Randomized" 51 case SHA384PSSDeterministic: 52 return "RSABSSA-SHA384-PSS-Deterministic" 53 case SHA384PSSZeroDeterministic: 54 return "RSABSSA-SHA384-PSSZero-Deterministic" 55 default: 56 return "invalid RSABSSA variant" 57 } 58 } 59 60 // Client is a type that implements the client side of the blind RSA 61 // protocol, described in https://www.rfc-editor.org/rfc/rfc9474.html#name-rsabssa-variants 62 type Client struct { 63 v Verifier 64 prefixLen int 65 } 66 67 func NewClient(v Variant, pk *rsa.PublicKey) (Client, error) { 68 verif, err := NewVerifier(v, pk) 69 if err != nil { 70 return Client{}, err 71 } 72 var prefixLen int 73 switch v { 74 case SHA384PSSDeterministic, SHA384PSSZeroDeterministic: 75 prefixLen = 0 76 case SHA384PSSRandomized, SHA384PSSZeroRandomized: 77 prefixLen = 32 78 default: 79 return Client{}, ErrInvalidVariant 80 } 81 82 return Client{verif, prefixLen}, nil 83 } 84 85 type State struct { 86 // The hashed and encoded message being signed 87 encodedMsg []byte 88 89 // Inverse of the blinding factor produced by the Verifier 90 rInv *big.Int 91 } 92 93 // Prepare is the process by which the message to be signed and 94 // verified is prepared for input to the blind signing protocol. 95 func (c Client) Prepare(random io.Reader, message []byte) ([]byte, error) { 96 if random == nil { 97 return nil, common.ErrInvalidRandomness 98 } 99 100 prefix := make([]byte, c.prefixLen) 101 _, err := io.ReadFull(random, prefix) 102 if err != nil { 103 return nil, err 104 } 105 106 return append(append([]byte{}, prefix...), message...), nil 107 } 108 109 // Blind initializes the blind RSA protocol using an input message and source of randomness. 110 // This function fails if randomness was not provided. 111 func (c Client) Blind(random io.Reader, preparedMessage []byte) (blindedMsg []byte, state State, err error) { 112 if random == nil { 113 return nil, State{}, common.ErrInvalidRandomness 114 } 115 116 salt := make([]byte, c.v.SaltLength) 117 _, err = io.ReadFull(random, salt) 118 if err != nil { 119 return nil, State{}, err 120 } 121 122 r, rInv, err := common.GenerateBlindingFactor(random, c.v.pk.N) 123 if err != nil { 124 return nil, State{}, err 125 } 126 127 return c.fixedBlind(preparedMessage, salt, r, rInv) 128 } 129 130 func (c Client) fixedBlind(message, salt []byte, r, rInv *big.Int) (blindedMsg []byte, state State, err error) { 131 encodedMsg, err := common.EncodeMessageEMSAPSS(message, c.v.pk.N, c.v.Hash.New(), salt) 132 if err != nil { 133 return nil, State{}, err 134 } 135 136 m := new(big.Int).SetBytes(encodedMsg) 137 138 bigE := big.NewInt(int64(c.v.pk.E)) 139 x := new(big.Int).Exp(r, bigE, c.v.pk.N) 140 z := new(big.Int).Set(m) 141 z.Mul(z, x) 142 z.Mod(z, c.v.pk.N) 143 144 kLen := (c.v.pk.N.BitLen() + 7) / 8 145 blindedMsg = make([]byte, kLen) 146 z.FillBytes(blindedMsg) 147 148 return blindedMsg, State{encodedMsg, rInv}, nil 149 } 150 151 func (c Client) Finalize(state State, blindedSig []byte) ([]byte, error) { 152 kLen := (c.v.pk.N.BitLen() + 7) / 8 153 if len(blindedSig) != kLen { 154 return nil, common.ErrUnexpectedSize 155 } 156 157 z := new(big.Int).SetBytes(blindedSig) 158 s := new(big.Int).Set(state.rInv) 159 s.Mul(s, z) 160 s.Mod(s, c.v.pk.N) 161 162 sig := make([]byte, kLen) 163 s.FillBytes(sig) 164 165 err := common.VerifyBlindSignature(keys.NewBigPublicKey(c.v.pk), state.encodedMsg, sig) 166 if err != nil { 167 return nil, err 168 } 169 170 return sig, nil 171 } 172 173 // Verify verifies the input (message, signature) pair and produces an error upon failure. 174 func (c Client) Verify(message, signature []byte) error { return c.v.Verify(message, signature) } 175 176 type Verifier struct { 177 // Public key of the Signer 178 pk *rsa.PublicKey 179 rsa.PSSOptions 180 } 181 182 func NewVerifier(v Variant, pk *rsa.PublicKey) (Verifier, error) { 183 switch v { 184 case SHA384PSSRandomized, SHA384PSSDeterministic: 185 return Verifier{pk, rsa.PSSOptions{Hash: crypto.SHA384, SaltLength: crypto.SHA384.Size()}}, nil 186 case SHA384PSSZeroRandomized, SHA384PSSZeroDeterministic: 187 return Verifier{pk, rsa.PSSOptions{Hash: crypto.SHA384, SaltLength: 0}}, nil 188 default: 189 return Verifier{}, ErrInvalidVariant 190 } 191 } 192 193 // Verify verifies the input (message, signature) pair and produces an error upon failure. 194 func (v Verifier) Verify(message, signature []byte) error { 195 return common.VerifyMessageSignature(message, signature, v.SaltLength, keys.NewBigPublicKey(v.pk), v.Hash) 196 } 197 198 // Signer structure represents the signing server in the blind RSA protocol. 199 // It carries the raw RSA private key used for signing blinded messages. 200 type Signer struct { 201 // An RSA private key 202 sk *rsa.PrivateKey 203 } 204 205 // NewSigner creates a new Signer for the blind RSA protocol using an RSA private key. 206 func NewSigner(sk *rsa.PrivateKey) Signer { 207 return Signer{ 208 sk: sk, 209 } 210 } 211 212 // BlindSign blindly computes the RSA operation using the Signer's private key on the blinded 213 // message input, if it's of valid length, and returns an error should the function fail. 214 // 215 // See the specification for more details: 216 // https://www.rfc-editor.org/rfc/rfc9474.html#name-blindsign 217 func (signer Signer) BlindSign(data []byte) ([]byte, error) { 218 kLen := (signer.sk.N.BitLen() + 7) / 8 219 if len(data) != kLen { 220 return nil, common.ErrUnexpectedSize 221 } 222 223 m := new(big.Int).SetBytes(data) 224 if m.Cmp(signer.sk.N) > 0 { 225 return nil, common.ErrInvalidMessageLength 226 } 227 228 s, err := common.DecryptAndCheck(rand.Reader, keys.NewBigPrivateKey(signer.sk), m) 229 if err != nil { 230 return nil, err 231 } 232 233 blindSig := make([]byte, kLen) 234 s.FillBytes(blindSig) 235 236 return blindSig, nil 237 } 238 239 var ( 240 ErrInvalidVariant = common.ErrInvalidVariant 241 ErrUnexpectedSize = common.ErrUnexpectedSize 242 ErrInvalidMessageLength = common.ErrInvalidMessageLength 243 ErrInvalidBlind = common.ErrInvalidBlind 244 ErrInvalidRandomness = common.ErrInvalidRandomness 245 ErrUnsupportedHashFunction = common.ErrUnsupportedHashFunction 246 )