github.com/cranelv/ethereum_mpc@v0.0.0-20191031014521-23aeb1415092/mpcService/crypto/mpc_functions.go (about) 1 package crypto 2 3 import ( 4 "crypto/ecdsa" 5 "crypto/rand" 6 "errors" 7 "math/big" 8 "github.com/ethereum/go-ethereum/crypto" 9 "github.com/ethereum/go-ethereum/common/math" 10 "github.com/ethereum/go-ethereum/common" 11 "github.com/ethereum/go-ethereum/log" 12 "crypto/elliptic" 13 "io" 14 ) 15 var ( 16 Secp256k1N, _ = new(big.Int).SetString("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", 16) 17 Secp256k1halfN = new(big.Int).Div(Secp256k1N, big.NewInt(2)) 18 one = new(big.Int).SetInt64(1) 19 ) 20 func UintRand(MaxValue uint64) (uint64, error) { 21 num, err := rand.Int(rand.Reader, new(big.Int).SetUint64(MaxValue)) 22 if err != nil { 23 return 0, err 24 } 25 26 return num.Uint64(), nil 27 } 28 // randFieldElement returns a random element of the field underlying the given 29 // curve using the procedure given in [NSA] A.2.1. 30 func RandFieldElement(c elliptic.Curve,) (k *big.Int, err error) { 31 params := c.Params() 32 b := make([]byte, params.BitSize/8+8) 33 _, err = io.ReadFull(rand.Reader, b) 34 if err != nil { 35 return 36 } 37 38 k = new(big.Int).SetBytes(b) 39 n := new(big.Int).Sub(params.N, one) 40 k.Mod(k, n) 41 k.Add(k, one) 42 return 43 } 44 45 func GetRandCoefficients(num int) ([]*big.Int, error) { 46 randCoefficient := make([]*big.Int, num) 47 for i := 0; i < num; i++ { 48 key, err := RandFieldElement(crypto.S256()) 49 if err != nil { 50 return nil, err 51 } 52 randCoefficient[i] = key 53 } 54 55 return randCoefficient, nil 56 } 57 58 func EvaluatePoly(coefficient []*big.Int, x *big.Int) *big.Int { 59 degree := len(coefficient) - 1 60 sumx := make([]big.Int, degree+1) 61 for i := 0; i <= degree; i++ { 62 sumx[i].Set(coefficient[i]) 63 } 64 65 for i := 1; i <= degree; i++ { 66 for j := i; j <= degree; j++ { 67 sumx[j].Mul(&sumx[j], x) 68 sumx[j].Mod(&sumx[j], Secp256k1N) 69 } 70 } 71 72 sum := big.NewInt(0) 73 for i := 0; i < len(sumx); i++ { 74 sum.Add(sum, &sumx[i]) 75 sum.Mod(sum, Secp256k1N) 76 } 77 78 return sum 79 } 80 81 func evaluateB(x []*big.Int) []*big.Int { 82 k := len(x) 83 b := make([]*big.Int, k) 84 for i := 0; i < k; i++ { 85 b[i] = evaluateb(x, i) 86 } 87 88 return b 89 } 90 91 func evaluateb(x []*big.Int, i int) *big.Int { 92 k := len(x) 93 sum := big.NewInt(1) 94 temp1 := big.NewInt(1) 95 temp2 := big.NewInt(1) 96 for j := 0; j < k; j++ { 97 if j != i { 98 temp1.Sub(x[j], x[i]) 99 temp1.ModInverse(temp1, Secp256k1N) 100 temp2.Mul(x[j], temp1) 101 sum.Mul(sum, temp2) 102 sum.Mod(sum, Secp256k1N) 103 } else { 104 continue 105 } 106 } 107 108 return sum 109 } 110 111 // Lagrange's polynomial interpolation algorithm 112 func Lagrange(f []*big.Int, x []*big.Int) *big.Int { 113 degree := len(x) - 1 114 b := evaluateB(x) 115 s := big.NewInt(0) 116 temp1 := big.NewInt(1) 117 118 for i := 0; i < degree+1; i++ { 119 temp1.Mul(f[i], b[i]) 120 s.Add(s, temp1) 121 s.Mod(s, Secp256k1N) 122 } 123 124 return s 125 } 126 127 func TransSignature(R *big.Int, S *big.Int, V uint64) ([]byte, error) { 128 if S.Cmp(new(big.Int).Div(Secp256k1N, big.NewInt(2))) > 0 { 129 V ^= 1 130 S.Sub(Secp256k1N,S) 131 } 132 133 sig := make([]byte, 65) 134 copy(sig[:], math.PaddedBigBytes(R, 32)) 135 copy(sig[32:], math.PaddedBigBytes(S, 32)) 136 sig[64] = byte(V) 137 return sig, nil 138 } 139 140 func SenderEcrecover(sighash, sig []byte) (common.Address, error) { 141 log.Info("SenderEcrecover, sigHash:%s, sig:%s", common.ToHex(sighash), common.ToHex(sig)) 142 143 pub, err := crypto.Ecrecover(sighash, sig) 144 if err != nil { 145 log.Error("SenderEcrecover, crypto Ecrecover fail, err:%s", err.Error()) 146 return common.Address{}, err 147 } 148 if len(pub) == 0 || pub[0] != 4 { 149 log.Error("SenderEcrecover, pub's value isn't zero in first byte") 150 return common.Address{}, errors.New("invalid public key") 151 } 152 var addr common.Address 153 copy(addr[:], crypto.Keccak256(pub[1:])[12:]) 154 return addr, nil 155 } 156 157 func ValidatePublicKey(k *ecdsa.PublicKey) bool { 158 return k != nil && k.X != nil && k.Y != nil && k.X.Sign() != 0 && k.Y.Sign() != 0 159 } 160 161 func ValidatePrivateKey(k *big.Int) bool { 162 if k == nil || k.Sign() == 0 { 163 return false 164 } 165 166 return true 167 }