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

     1  package jcc
     2  
     3  import (
     4  	"crypto/sha256"
     5  	"github.com/ronperry/cryptoedge/eccutil"
     6  	"math/big"
     7  )
     8  
     9  // Convinience Signer abstraction
    10  
    11  // BlindingServer is holds a blinding server
    12  type BlindingServer struct {
    13  	PubKey     *eccutil.Point
    14  	privKey    []byte
    15  	curve      *eccutil.Curve
    16  	uniqueTest func([32]byte) bool
    17  }
    18  
    19  // Fakeunique is a test function for the uniqueness-test. Must be implemented for production use
    20  func Fakeunique(x [32]byte) bool {
    21  	return true
    22  }
    23  
    24  // NewBlindingServer creates a new BlindingServer
    25  func NewBlindingServer(privkey []byte, pubkey *eccutil.Point, curve *eccutil.Curve, uniqueTest func([32]byte) bool) *BlindingServer {
    26  	bs := new(BlindingServer)
    27  	bs.PubKey = pubkey
    28  	bs.privKey = privkey
    29  	bs.curve = curve
    30  	bs.uniqueTest = uniqueTest
    31  	return bs
    32  }
    33  
    34  func (bs BlindingServer) uniqueToken(nv []byte, point *eccutil.Point) [32]byte {
    35  	t := make([]byte, len(nv))
    36  	copy(t, nv)
    37  	t = append(t, point.X.Bytes()...)
    38  	t = append(t, point.Y.Bytes()...)
    39  	return sha256.Sum256(t)
    40  }
    41  
    42  // Sign a blind message, return signature. callback for checking bmsg -> nv uniqueness. r and s are returned to client. r is public for verification
    43  func (bs BlindingServer) Sign(bmsg *eccutil.Point) (r, s *eccutil.Point, err error) {
    44  	// 		r = nv x blind message (POINT);
    45  	// 		s = (nv+ns) x blind message (POINT)
    46  	// 		Test that nv produces point (not infinity etc)
    47  	// 		ns is the privat key of the signer
    48  	//		record nv,blind message. protect priv-key of signer
    49  	// Generate nv and test if it does not produce infinity
    50  	// testunique(hash(bmsg,nv))==true
    51  	var loopcount int
    52  	_, err = bs.curve.TestPoint(bmsg.X, bmsg.Y, bs.PubKey.X, bs.PubKey.Y) // reflection
    53  	if err != nil {
    54  		return nil, nil, err
    55  	}
    56  	_, err = bs.curve.TestPoint(bmsg.X, bmsg.Y, bs.curve.Params.Gx, bs.curve.Params.Gx) // reflection generator
    57  	if err != nil {
    58  		return nil, nil, err
    59  	}
    60  	for {
    61  		if loopcount > MaxLoopCount {
    62  			return nil, nil, eccutil.ErrMaxLoop
    63  		}
    64  		loopcount++
    65  		nv, err := bs.curve.GenNV()
    66  		if err != nil {
    67  			return nil, nil, err
    68  		}
    69  		// Check for unique parameters
    70  		if !bs.uniqueTest(bs.uniqueToken(nv, bmsg)) {
    71  			continue
    72  		}
    73  		//rt := new(Point)
    74  		rt := bs.curve.ScalarMult(bmsg, nv)
    75  		_, err = bs.curve.TestPoint(rt.X, rt.Y, bs.PubKey.X, bs.PubKey.Y) // should never happen
    76  		if err != nil {
    77  			continue
    78  		}
    79  		_, err = bs.curve.TestPoint(rt.X, rt.Y, bs.curve.Params.Gx, bs.curve.Params.Gx) // should never happen
    80  		if err != nil {
    81  			continue
    82  		}
    83  
    84  		nvprivsum := new(big.Int)
    85  		privi := new(big.Int)
    86  		nvi := new(big.Int)
    87  		nvi.SetBytes(nv)
    88  		privi.SetBytes(bs.privKey)
    89  		nvprivsum = nvprivsum.Add(nvi, privi)
    90  		st := bs.curve.ScalarMult(bmsg, nvprivsum.Bytes())
    91  		_, err = bs.curve.TestPoint(st.X, st.Y, bs.PubKey.X, bs.PubKey.Y) // should never happen
    92  		if err != nil {
    93  			continue
    94  		}
    95  		_, err = bs.curve.TestPoint(st.X, st.Y, bs.curve.Params.Gx, bs.curve.Params.Gy) // should never happen
    96  		if err != nil {
    97  			continue
    98  		}
    99  		_, err = bs.curve.TestPoint(st.X, st.Y, rt.X, rt.Y) // should never happen
   100  		if err != nil {
   101  			continue
   102  		}
   103  		return rt, st, nil
   104  	}
   105  }