Skip to content

Commit be54248

Browse files
authored
Merge branch 'master' into bls12/hashG2
2 parents fe4f101 + 2d22325 commit be54248

24 files changed

+1390
-160
lines changed

blindsign/blindrsa/blindrsa.go

+215
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
package blindrsa
2+
3+
// This package implements the blind RSA protocol based on the CFRG specification:
4+
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-rsa-blind-signatures-02
5+
6+
import (
7+
"crypto/rand"
8+
"crypto/rsa"
9+
"crypto/subtle"
10+
"errors"
11+
"hash"
12+
"io"
13+
"math/big"
14+
15+
"github.com/cloudflare/circl/blindsign"
16+
)
17+
18+
// An RSAVerifier represents a Verifier in the RSA blind signature protocol.
19+
// It carries state needed to produce and validate an RSA blind signature.
20+
type RSAVerifier struct {
21+
// Public key of the Signer
22+
pk *rsa.PublicKey
23+
24+
// Hash function used in producing the message signature
25+
hash hash.Hash
26+
}
27+
28+
// NewRSAVerifier creates a new RSAVerifier using the corresponding Signer parameters.
29+
func NewRSAVerifier(pk *rsa.PublicKey, hash hash.Hash) RSAVerifier {
30+
return RSAVerifier{
31+
pk: pk,
32+
hash: hash,
33+
}
34+
}
35+
36+
func encodeMessageEMSAPSS(message []byte, key *rsa.PublicKey, hash hash.Hash, salt []byte) ([]byte, error) {
37+
hash.Reset() // Ensure the hash state is cleared
38+
hash.Write(message)
39+
digest := hash.Sum(nil)
40+
hash.Reset()
41+
emBits := key.N.BitLen() - 1
42+
encodedMsg, err := emsaPSSEncode(digest[:], emBits, salt, hash)
43+
return encodedMsg, err
44+
}
45+
46+
func generateBlindingFactor(random io.Reader, key *rsa.PublicKey) (*big.Int, *big.Int, error) {
47+
randReader := random
48+
if randReader == nil {
49+
randReader = rand.Reader
50+
}
51+
r, err := rand.Int(randReader, key.N)
52+
if err != nil {
53+
return nil, nil, err
54+
}
55+
56+
if r.Sign() == 0 {
57+
r = bigOne
58+
}
59+
rInv := new(big.Int).ModInverse(r, key.N)
60+
if rInv == nil {
61+
return nil, nil, ErrInvalidBlind
62+
}
63+
64+
return r, rInv, nil
65+
}
66+
67+
func (v RSAVerifier) fixedBlind(message, salt []byte, r, rInv *big.Int) ([]byte, blindsign.VerifierState, error) {
68+
encodedMsg, err := encodeMessageEMSAPSS(message, v.pk, v.hash, salt)
69+
if err != nil {
70+
return nil, nil, err
71+
}
72+
73+
m := new(big.Int).SetBytes(encodedMsg)
74+
75+
bigE := big.NewInt(int64(v.pk.E))
76+
x := new(big.Int).Exp(r, bigE, v.pk.N)
77+
z := new(big.Int).Set(m)
78+
z.Mul(z, x)
79+
z.Mod(z, v.pk.N)
80+
81+
blindedMsg := z.Bytes()
82+
83+
return blindedMsg, RSAVerifierState{
84+
encodedMsg: encodedMsg,
85+
verifier: v,
86+
rInv: rInv,
87+
}, nil
88+
}
89+
90+
// Blind initializes the blind RSA protocol using an input message and source of randomness. The
91+
// signature includes a randomly generated PSS salt whose length equals the size of the underlying
92+
// hash function. This function fails if randomness was not provided.
93+
//
94+
// See the specification for more details:
95+
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-rsa-blind-signatures-02#section-5.1.1
96+
func (v RSAVerifier) Blind(random io.Reader, message []byte) ([]byte, blindsign.VerifierState, error) {
97+
if random == nil {
98+
return nil, nil, ErrInvalidRandomness
99+
}
100+
101+
salt := make([]byte, v.hash.Size())
102+
_, err := random.Read(salt)
103+
if err != nil {
104+
return nil, nil, err
105+
}
106+
107+
r, rInv, err := generateBlindingFactor(random, v.pk)
108+
if err != nil {
109+
return nil, nil, err
110+
}
111+
112+
return v.fixedBlind(message, salt, r, rInv)
113+
}
114+
115+
// An RSAVerifierState carries state needed to complete the blind signature protocol
116+
// as a verifier.
117+
type RSAVerifierState struct {
118+
// An RSA verifier carrying Signer verification state
119+
verifier RSAVerifier
120+
121+
// The hashed and encoded message being signed
122+
encodedMsg []byte
123+
124+
// Inverse of the blinding factor produced by the Verifier
125+
rInv *big.Int
126+
}
127+
128+
func verifyBlindSignature(pub *rsa.PublicKey, hashed, sig []byte) error {
129+
m := new(big.Int).SetBytes(hashed)
130+
bigSig := new(big.Int).SetBytes(sig)
131+
132+
c := encrypt(new(big.Int), pub, bigSig)
133+
if subtle.ConstantTimeCompare(m.Bytes(), c.Bytes()) == 1 {
134+
return nil
135+
} else {
136+
return rsa.ErrVerification
137+
}
138+
}
139+
140+
// Finalize computes and outputs the final signature, if it's valid. Otherwise, it returns an error.
141+
//
142+
// See the specification for more details:
143+
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-rsa-blind-signatures-02#section-5.1.3
144+
func (state RSAVerifierState) Finalize(data []byte) ([]byte, error) {
145+
kLen := (state.verifier.pk.N.BitLen() + 7) / 8
146+
if len(data) != kLen {
147+
return nil, ErrUnexpectedSize
148+
}
149+
150+
z := new(big.Int).SetBytes(data)
151+
s := new(big.Int).Set(state.rInv)
152+
s.Mul(s, z)
153+
s.Mod(s, state.verifier.pk.N)
154+
155+
sig := s.Bytes()
156+
157+
err := verifyBlindSignature(state.verifier.pk, state.encodedMsg, sig)
158+
if err != nil {
159+
return nil, err
160+
}
161+
162+
return sig, nil
163+
}
164+
165+
// An RSASigner represents the Signer in the blind RSA protocol.
166+
// It carries the raw RSA private key used for signing blinded messages.
167+
type RSASigner struct {
168+
// An RSA private key
169+
sk *rsa.PrivateKey
170+
}
171+
172+
// NewRSASigner creates a new Signer for the blind RSA protocol using an RSA private key.
173+
func NewRSASigner(sk *rsa.PrivateKey) RSASigner {
174+
return RSASigner{
175+
sk: sk,
176+
}
177+
}
178+
179+
// BlindSign blindly computes the RSA operation using the Signer's private key on the blinded
180+
// message input, if it's of valid length, and returns an error should the function fail.
181+
//
182+
// See the specification for more details:
183+
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-rsa-blind-signatures-02#section-5.1.2
184+
func (signer RSASigner) BlindSign(data []byte) ([]byte, error) {
185+
kLen := (signer.sk.N.BitLen() + 7) / 8
186+
if len(data) != kLen {
187+
return nil, ErrUnexpectedSize
188+
}
189+
190+
m := new(big.Int).SetBytes(data)
191+
if m.Cmp(signer.sk.N) > 0 {
192+
return nil, ErrInvalidMessageLength
193+
}
194+
195+
s, err := decryptAndCheck(rand.Reader, signer.sk, m)
196+
if err != nil {
197+
return nil, err
198+
}
199+
200+
return s.Bytes(), nil
201+
}
202+
203+
var (
204+
// ErrUnexpectedSize is the error used if the size of a parameter does not match its expected value.
205+
ErrUnexpectedSize = errors.New("blindsign/blindrsa: unexpected input size")
206+
207+
// ErrInvalidMessageLength is the error used if the size of a protocol message does not match its expected value.
208+
ErrInvalidMessageLength = errors.New("blindsign/blindrsa: invalid message length")
209+
210+
// ErrInvalidBlind is the error used if the blind generated by the Verifier fails.
211+
ErrInvalidBlind = errors.New("blindsign/blindrsa: invalid blind")
212+
213+
// ErrInvalidRandomness is the error used if caller did not provide randomness to the Blind() function.
214+
ErrInvalidRandomness = errors.New("blindsign/blindrsa: invalid random parameter")
215+
)

0 commit comments

Comments
 (0)