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 }