github.com/ronperry/cryptoedge@v0.0.0-20150815114006-cc363e290743/singhdas/requestor.go (about)

     1  // Package singhdas implementes "A Novel Proficient Blind Signature Scheme using ECC" by Nitu Singh and Sumanjit Das
     2  // Some of the tests/verifications are not necessary but done anyways.
     3  package singhdas
     4  
     5  import (
     6  	"github.com/ronperry/cryptoedge/eccutil"
     7  	"math/big"
     8  )
     9  
    10  // SignerClient encapsulates a client to a signer
    11  type SignerClient struct {
    12  	pubkey *eccutil.Point
    13  	curve  *eccutil.Curve
    14  }
    15  
    16  // BlindingFactorsInt holds parameters required for unblinding
    17  type BlindingFactorsInt struct {
    18  	r2          *big.Int
    19  	r1inv       *big.Int
    20  	r1          *big.Int
    21  	N           *big.Int
    22  	Hm          *big.Int
    23  	R           *eccutil.Point
    24  	SignerBlind *eccutil.Point
    25  	used        bool
    26  }
    27  
    28  // BlindMessageInt encapsulates a blinded message
    29  type BlindMessageInt struct {
    30  	Message     *big.Int
    31  	SignerBlind *eccutil.Point
    32  }
    33  
    34  // SignatureInt is a plain signature
    35  type SignatureInt struct {
    36  	S  *big.Int
    37  	r2 *big.Int
    38  	R  *eccutil.Point
    39  	Hm *big.Int
    40  }
    41  
    42  // NewSignerClient returns a new client to a signer over curve with publickey
    43  func NewSignerClient(pubkey *eccutil.Point, curve *eccutil.Curve) *SignerClient {
    44  	sc := new(SignerClient)
    45  	sc.pubkey = pubkey
    46  	sc.curve = curve
    47  	return sc
    48  }
    49  
    50  // Blind blinds a message msg for signerBlind and returns the blinded message and the blinding factors
    51  func (client SignerClient) Blind(message []byte, signerBlind *eccutil.Point) (blindMessage *BlindMessageInt, blindingFactors *BlindingFactorsInt, err error) {
    52  	var loopcount int
    53  	var M, N, r2 *big.Int
    54  	var R *eccutil.Point
    55  	r1, err := client.curve.ExtractR(signerBlind)
    56  	if err != nil {
    57  		return nil, nil, eccutil.ErrBadBlindParam
    58  	}
    59  	if !client.curve.WithinRange(r1) {
    60  		return nil, nil, eccutil.ErrBadBlindParam
    61  	}
    62  	for {
    63  		if loopcount > eccutil.MaxLoopCount {
    64  			return nil, nil, eccutil.ErrMaxLoop
    65  		}
    66  		loopcount++
    67  		M, err = client.curve.RandomElement()
    68  		if err != nil {
    69  			continue
    70  		}
    71  		N, err = client.curve.RandomElement()
    72  		if err != nil {
    73  			continue
    74  		}
    75  		MQ := client.curve.ScalarMult(signerBlind, M.Bytes())
    76  		NG := client.curve.ScalarBaseMult(N.Bytes())
    77  		R = client.curve.AddPoints(MQ, NG)
    78  		r2, err = client.curve.ExtractR(R)
    79  		if err != nil {
    80  			continue
    81  		}
    82  		if !client.curve.WithinRange(r2) {
    83  			continue
    84  		}
    85  		_, err = client.curve.TestParams(M, N, R.X, R.Y, r1)
    86  		if err != nil {
    87  			return nil, nil, eccutil.ErrBadBlindParam
    88  		}
    89  		break
    90  	}
    91  	r2inv, err := client.curve.ModInverse(r2)
    92  	if err != nil {
    93  		return nil, nil, eccutil.ErrBadBlindParam // should always be caught before
    94  	}
    95  	r1inv, err := client.curve.ModInverse(r1)
    96  	if err != nil {
    97  		return nil, nil, eccutil.ErrBadBlindParam // should always be caught before
    98  	}
    99  	Hm := client.curve.GenHash(message)
   100  	ms := client.curve.Mod(eccutil.ManyMult(M, Hm, r1, r2inv))
   101  
   102  	bf := new(BlindingFactorsInt)
   103  	bf.r2 = r2
   104  	bf.r1inv = r1inv
   105  	bf.r1 = r1
   106  	bf.N = N
   107  	bf.Hm = Hm
   108  	bf.R = R
   109  	bf.SignerBlind = signerBlind
   110  
   111  	bm := new(BlindMessageInt)
   112  	bm.Message = ms
   113  	bm.SignerBlind = signerBlind
   114  
   115  	return bm, bf, nil
   116  }
   117  
   118  // UnBlind a signature using blinding factor
   119  func (client SignerClient) UnBlind(blindSignature *BlindSignatureInt, blindingFactors *BlindingFactorsInt) (*SignatureInt, error) {
   120  	if !client.curve.WithinRange(blindSignature.S) {
   121  		return nil, eccutil.ErrBadBlindParam
   122  	}
   123  	if !client.curve.WithinRange(blindingFactors.r1) {
   124  		return nil, eccutil.ErrBadBlindParam
   125  	}
   126  	if blindingFactors.used {
   127  		return nil, eccutil.ErrParamReuse
   128  	}
   129  	NHm := eccutil.ManyMult(blindingFactors.N, blindingFactors.Hm)
   130  	Sr2r1inv := eccutil.ManyMult(blindSignature.S, blindingFactors.r2, blindingFactors.r1inv)
   131  	St := eccutil.ManyAdd(Sr2r1inv, NHm)
   132  	S := client.curve.Mod(St)
   133  	sig := new(SignatureInt)
   134  	sig.S = S
   135  	sig.r2 = blindingFactors.r2
   136  	sig.R = blindingFactors.R
   137  	sig.Hm = blindingFactors.Hm
   138  	return sig, nil
   139  }