Skip to content

Commit

Permalink
Merge pull request #1 from armfazh/pull445
Browse files Browse the repository at this point in the history
Refactoring to hide internals.
  • Loading branch information
chris-wood authored Jun 20, 2023
2 parents 47393f1 + 8653635 commit 4d5ca64
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 59 deletions.
67 changes: 26 additions & 41 deletions blindsign/blindrsa/brsa.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,14 @@ import (
"crypto"
"crypto/rand"
"crypto/rsa"
"errors"
"hash"
"io"
"math/big"

"github.com/cloudflare/circl/blindsign/blindrsa/internal/common"
"github.com/cloudflare/circl/blindsign/blindrsa/internal/keys"
)

var errUnsupportedHashFunction = errors.New("unsupported hash function")

// An randomBRSAVerifier represents a Verifier in the RSA blind signature protocol.
// It carries state needed to produce and validate an RSA signature produced
// using the blind RSA protocol.
Expand Down Expand Up @@ -70,7 +68,7 @@ type Verifier interface {
// This corresponds to the RSABSSA-SHA384-PSSZERO-Deterministic variant. See the specification for more details:
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-rsa-blind-signatures#name-rsabssa-variants
func NewDeterministicVerifier(pk *rsa.PublicKey, hash crypto.Hash) Verifier {
h := ConvertHashFunction(hash)
h := common.ConvertHashFunction(hash)
return determinsiticBRSAVerifier{
pk: pk,
cryptoHash: hash,
Expand All @@ -87,7 +85,7 @@ func (v determinsiticBRSAVerifier) Hash() hash.Hash {
// This corresponds to the RSABSSA-SHA384-PSS-Deterministic variant. See the specification for more details:
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-rsa-blind-signatures#name-rsabssa-variants
func NewVerifier(pk *rsa.PublicKey, hash crypto.Hash) Verifier {
h := ConvertHashFunction(hash)
h := common.ConvertHashFunction(hash)
return randomBRSAVerifier{
pk: pk,
cryptoHash: hash,
Expand All @@ -101,7 +99,7 @@ func (v randomBRSAVerifier) Hash() hash.Hash {
}

func fixedBlind(message, salt []byte, r, rInv *big.Int, pk *rsa.PublicKey, hash hash.Hash) ([]byte, VerifierState, error) {
encodedMsg, err := EncodeMessageEMSAPSS(message, pk.N, hash, salt)
encodedMsg, err := common.EncodeMessageEMSAPSS(message, pk.N, hash, salt)
if err != nil {
return nil, VerifierState{}, err
}
Expand Down Expand Up @@ -134,45 +132,38 @@ func fixedBlind(message, salt []byte, r, rInv *big.Int, pk *rsa.PublicKey, hash
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-rsa-blind-signatures-02#section-5.1.1
func (v determinsiticBRSAVerifier) Blind(random io.Reader, message []byte) ([]byte, VerifierState, error) {
if random == nil {
return nil, VerifierState{}, ErrInvalidRandomness
return nil, VerifierState{}, common.ErrInvalidRandomness
}

r, rInv, err := GenerateBlindingFactor(random, v.pk.N)
r, rInv, err := common.GenerateBlindingFactor(random, v.pk.N)
if err != nil {
return nil, VerifierState{}, err
}

return fixedBlind(message, nil, r, rInv, v.pk, v.hash)
}

func saltLength(opts *rsa.PSSOptions) int {
if opts == nil {
return rsa.PSSSaltLengthAuto
}
return opts.SaltLength
}

// FixedBlind runs the Blind function with fixed blind and salt inputs.
func (v determinsiticBRSAVerifier) FixedBlind(message, blind, salt []byte) ([]byte, VerifierState, error) {
if blind == nil {
return nil, VerifierState{}, ErrInvalidRandomness
return nil, VerifierState{}, common.ErrInvalidRandomness
}

r := new(big.Int).SetBytes(blind)
if r.Cmp(v.pk.N) >= 0 {
return nil, VerifierState{}, ErrInvalidBlind
return nil, VerifierState{}, common.ErrInvalidBlind
}
rInv := new(big.Int).ModInverse(r, v.pk.N)
if rInv == nil {
return nil, VerifierState{}, ErrInvalidBlind
return nil, VerifierState{}, common.ErrInvalidBlind
}

return fixedBlind(message, salt, r, rInv, v.pk, v.hash)
}

// Verify verifies the input (message, signature) pair and produces an error upon failure.
func (v determinsiticBRSAVerifier) Verify(message, signature []byte) error {
return VerifyMessageSignature(message, signature, 0, keys.NewBigPublicKey(v.pk), v.cryptoHash)
return common.VerifyMessageSignature(message, signature, 0, keys.NewBigPublicKey(v.pk), v.cryptoHash)
}

// Blind initializes the blind RSA protocol using an input message and source of randomness. The
Expand All @@ -183,7 +174,7 @@ func (v determinsiticBRSAVerifier) Verify(message, signature []byte) error {
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-rsa-blind-signatures-02#section-5.1.1
func (v randomBRSAVerifier) Blind(random io.Reader, message []byte) ([]byte, VerifierState, error) {
if random == nil {
return nil, VerifierState{}, ErrInvalidRandomness
return nil, VerifierState{}, common.ErrInvalidRandomness
}

salt := make([]byte, v.hash.Size())
Expand All @@ -192,7 +183,7 @@ func (v randomBRSAVerifier) Blind(random io.Reader, message []byte) ([]byte, Ver
return nil, VerifierState{}, err
}

r, rInv, err := GenerateBlindingFactor(random, v.pk.N)
r, rInv, err := common.GenerateBlindingFactor(random, v.pk.N)
if err != nil {
return nil, VerifierState{}, err
}
Expand All @@ -203,25 +194,25 @@ func (v randomBRSAVerifier) Blind(random io.Reader, message []byte) ([]byte, Ver
// FixedBlind runs the Blind function with fixed blind and salt inputs.
func (v randomBRSAVerifier) FixedBlind(message, blind, salt []byte) ([]byte, VerifierState, error) {
if blind == nil {
return nil, VerifierState{}, ErrInvalidRandomness
return nil, VerifierState{}, common.ErrInvalidRandomness
}

r := new(big.Int).SetBytes(blind)
if r.Cmp(v.pk.N) >= 0 {
return nil, VerifierState{}, ErrInvalidBlind
return nil, VerifierState{}, common.ErrInvalidBlind
}

rInv := new(big.Int).ModInverse(r, v.pk.N)
if rInv == nil {
return nil, VerifierState{}, ErrInvalidBlind
return nil, VerifierState{}, common.ErrInvalidBlind
}

return fixedBlind(message, salt, r, rInv, v.pk, v.hash)
}

// Verify verifies the input (message, signature) pair and produces an error upon failure.
func (v randomBRSAVerifier) Verify(message, signature []byte) error {
return VerifyMessageSignature(message, signature, v.hash.Size(), keys.NewBigPublicKey(v.pk), v.cryptoHash)
return common.VerifyMessageSignature(message, signature, v.hash.Size(), keys.NewBigPublicKey(v.pk), v.cryptoHash)
}

// An VerifierState carries state needed to complete the blind signature protocol
Expand Down Expand Up @@ -250,7 +241,7 @@ type VerifierState struct {
func (state VerifierState) Finalize(data []byte) ([]byte, error) {
kLen := (state.pk.N.BitLen() + 7) / 8
if len(data) != kLen {
return nil, ErrUnexpectedSize
return nil, common.ErrUnexpectedSize
}

z := new(big.Int).SetBytes(data)
Expand All @@ -261,7 +252,7 @@ func (state VerifierState) Finalize(data []byte) ([]byte, error) {
sig := make([]byte, kLen)
s.FillBytes(sig)

err := VerifyBlindSignature(keys.NewBigPublicKey(state.pk), state.encodedMsg, sig)
err := common.VerifyBlindSignature(keys.NewBigPublicKey(state.pk), state.encodedMsg, sig)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -304,15 +295,15 @@ func NewSigner(sk *rsa.PrivateKey) Signer {
func (signer Signer) BlindSign(data []byte) ([]byte, error) {
kLen := (signer.sk.N.BitLen() + 7) / 8
if len(data) != kLen {
return nil, ErrUnexpectedSize
return nil, common.ErrUnexpectedSize
}

m := new(big.Int).SetBytes(data)
if m.Cmp(signer.sk.N) > 0 {
return nil, ErrInvalidMessageLength
return nil, common.ErrInvalidMessageLength
}

s, err := DecryptAndCheck(rand.Reader, keys.NewBigPrivateKey(signer.sk), m)
s, err := common.DecryptAndCheck(rand.Reader, keys.NewBigPrivateKey(signer.sk), m)
if err != nil {
return nil, err
}
Expand All @@ -324,15 +315,9 @@ func (signer Signer) BlindSign(data []byte) ([]byte, error) {
}

var (
// ErrUnexpectedSize is the error used if the size of a parameter does not match its expected value.
ErrUnexpectedSize = errors.New("blindsign/blindrsa: unexpected input size")

// ErrInvalidMessageLength is the error used if the size of a protocol message does not match its expected value.
ErrInvalidMessageLength = errors.New("blindsign/blindrsa: invalid message length")

// ErrInvalidBlind is the error used if the blind generated by the Verifier fails.
ErrInvalidBlind = errors.New("blindsign/blindrsa: invalid blind")

// ErrInvalidRandomness is the error used if caller did not provide randomness to the Blind() function.
ErrInvalidRandomness = errors.New("blindsign/blindrsa: invalid random parameter")
ErrUnexpectedSize = common.ErrUnexpectedSize
ErrInvalidMessageLength = common.ErrInvalidMessageLength
ErrInvalidBlind = common.ErrInvalidBlind
ErrInvalidRandomness = common.ErrInvalidRandomness
ErrUnsupportedHashFunction = common.ErrUnsupportedHashFunction
)
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package blindrsa
package common

import (
"crypto"
Expand All @@ -25,7 +25,7 @@ func ConvertHashFunction(hash crypto.Hash) hash.Hash {
case crypto.SHA512:
return sha512.New()
default:
panic(errUnsupportedHashFunction)
panic(ErrUnsupportedHashFunction)
}
}

Expand Down Expand Up @@ -53,7 +53,7 @@ func GenerateBlindingFactor(random io.Reader, N *big.Int) (*big.Int, *big.Int, e
}

if r.Sign() == 0 {
r = bigOne
r.SetInt64(1)
}
rInv := new(big.Int).ModInverse(r, N)
if rInv == nil {
Expand Down Expand Up @@ -105,6 +105,13 @@ func VerifyBlindSignature(pub *keys.BigPublicKey, hashed, sig []byte) error {
}
}

func saltLength(opts *rsa.PSSOptions) int {
if opts == nil {
return rsa.PSSSaltLengthAuto
}
return opts.SaltLength
}

func verifyPSS(pub *keys.BigPublicKey, hash crypto.Hash, digest []byte, sig []byte, opts *rsa.PSSOptions) error {
if len(sig) != pub.Size() {
return rsa.ErrVerification
Expand All @@ -119,3 +126,20 @@ func verifyPSS(pub *keys.BigPublicKey, hash crypto.Hash, digest []byte, sig []by
em := m.FillBytes(make([]byte, emLen))
return emsaPSSVerify(digest, em, emBits, saltLength(opts), hash.New())
}

var (
// ErrUnexpectedSize is the error used if the size of a parameter does not match its expected value.
ErrUnexpectedSize = errors.New("blindsign/blindrsa: unexpected input size")

// ErrInvalidMessageLength is the error used if the size of a protocol message does not match its expected value.
ErrInvalidMessageLength = errors.New("blindsign/blindrsa: invalid message length")

// ErrInvalidBlind is the error used if the blind generated by the Verifier fails.
ErrInvalidBlind = errors.New("blindsign/blindrsa: invalid blind")

// ErrInvalidRandomness is the error used if caller did not provide randomness to the Blind() function.
ErrInvalidRandomness = errors.New("blindsign/blindrsa: invalid random parameter")

// ErrUnsupportedHashFunction is the error used if the specified hash is not supported.
ErrUnsupportedHashFunction = errors.New("blindsign/blindrsa: unsupported hash function")
)
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package blindrsa
package common

// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package blindrsa
package common

import (
"crypto/rand"
Expand Down
31 changes: 18 additions & 13 deletions blindsign/blindrsa/partiallyblindrsa/pbrsa.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"io"
"math/big"

"github.com/cloudflare/circl/blindsign/blindrsa"
"github.com/cloudflare/circl/blindsign/blindrsa/internal/common"
"github.com/cloudflare/circl/blindsign/blindrsa/internal/keys"
"golang.org/x/crypto/hkdf"
)
Expand Down Expand Up @@ -42,7 +42,7 @@ type randomizedVerifier struct {
// This corresponds to the RSAPBSSA-SHA384-PSS-Deterministic variant. See the specification for more details:
// https://datatracker.ietf.org/doc/html/draft-amjad-cfrg-partially-blind-rsa#name-rsapbssa-variants
func NewVerifier(pk *rsa.PublicKey, hash crypto.Hash) Verifier {
h := blindrsa.ConvertHashFunction(hash)
h := common.ConvertHashFunction(hash)
return randomizedVerifier{
pk: keys.NewBigPublicKey(pk),
cryptoHash: hash,
Expand Down Expand Up @@ -115,7 +115,7 @@ func augmentPrivateKey(h crypto.Hash, sk *keys.BigPrivateKey, metadata []byte) *
}

func fixedPartiallyBlind(message, salt []byte, r, rInv *big.Int, pk *keys.BigPublicKey, hash hash.Hash) ([]byte, VerifierState, error) {
encodedMsg, err := blindrsa.EncodeMessageEMSAPSS(message, pk.N, hash, salt)
encodedMsg, err := common.EncodeMessageEMSAPSS(message, pk.N, hash, salt)
if err != nil {
return nil, VerifierState{}, err
}
Expand Down Expand Up @@ -165,7 +165,7 @@ type Verifier interface {
// https://datatracker.ietf.org/doc/html/draft-amjad-cfrg-partially-blind-rsa-00#name-blind
func (v randomizedVerifier) Blind(random io.Reader, message, metadata []byte) ([]byte, VerifierState, error) {
if random == nil {
return nil, VerifierState{}, blindrsa.ErrInvalidRandomness
return nil, VerifierState{}, common.ErrInvalidRandomness
}

salt := make([]byte, v.hash.Size())
Expand All @@ -174,7 +174,7 @@ func (v randomizedVerifier) Blind(random io.Reader, message, metadata []byte) ([
return nil, VerifierState{}, err
}

r, rInv, err := blindrsa.GenerateBlindingFactor(random, v.pk.N)
r, rInv, err := common.GenerateBlindingFactor(random, v.pk.N)
if err != nil {
return nil, VerifierState{}, err
}
Expand All @@ -192,7 +192,7 @@ func (v randomizedVerifier) Blind(random io.Reader, message, metadata []byte) ([
func (v randomizedVerifier) Verify(message, metadata, signature []byte) error {
metadataKey := augmentPublicKey(v.cryptoHash, v.pk, metadata)
inputMsg := encodeMessageMetadata(message, metadata)
return blindrsa.VerifyMessageSignature(inputMsg, signature, v.hash.Size(), metadataKey, v.cryptoHash)
return common.VerifyMessageSignature(inputMsg, signature, v.hash.Size(), metadataKey, v.cryptoHash)
}

// Hash returns the hash function associated with the Verifier.
Expand Down Expand Up @@ -226,7 +226,7 @@ type VerifierState struct {
func (state VerifierState) Finalize(data []byte) ([]byte, error) {
kLen := (state.pk.N.BitLen() + 7) / 8
if len(data) != kLen {
return nil, blindrsa.ErrUnexpectedSize
return nil, common.ErrUnexpectedSize
}

z := new(big.Int).SetBytes(data)
Expand All @@ -237,7 +237,7 @@ func (state VerifierState) Finalize(data []byte) ([]byte, error) {
sig := make([]byte, kLen)
s.FillBytes(sig)

err := blindrsa.VerifyBlindSignature(state.pk, state.encodedMsg, sig)
err := common.VerifyBlindSignature(state.pk, state.encodedMsg, sig)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -295,17 +295,17 @@ func NewSigner(sk *rsa.PrivateKey, h crypto.Hash) (Signer, error) {
func (signer Signer) BlindSign(data, metadata []byte) ([]byte, error) {
kLen := (signer.sk.Pk.N.BitLen() + 7) / 8
if len(data) != kLen {
return nil, blindrsa.ErrUnexpectedSize
return nil, common.ErrUnexpectedSize
}

m := new(big.Int).SetBytes(data)
if m.Cmp(signer.sk.Pk.N) > 0 {
return nil, blindrsa.ErrInvalidMessageLength
return nil, common.ErrInvalidMessageLength
}

skPrime := augmentPrivateKey(signer.h, signer.sk, metadata)

s, err := blindrsa.DecryptAndCheck(rand.Reader, skPrime, m)
s, err := common.DecryptAndCheck(rand.Reader, skPrime, m)
if err != nil {
return nil, err
}
Expand All @@ -316,5 +316,10 @@ func (signer Signer) BlindSign(data, metadata []byte) ([]byte, error) {
return blindSig, nil
}

// ErrInvalidPrivateKey is the error used if a private key is invalid
var ErrInvalidPrivateKey = errors.New("blindsign/blindrsa/partiallyblindrsa: invalid private key")
var (
// ErrInvalidPrivateKey is the error used if a private key is invalid
ErrInvalidPrivateKey = errors.New("blindsign/blindrsa/partiallyblindrsa: invalid private key")
ErrUnexpectedSize = common.ErrUnexpectedSize
ErrInvalidMessageLength = common.ErrInvalidMessageLength
ErrInvalidRandomness = common.ErrInvalidRandomness
)
2 changes: 2 additions & 0 deletions blindsign/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Package blindsign provides blind signature schemes.
package blindsign

0 comments on commit 4d5ca64

Please sign in to comment.