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 }