ecc加密共識鎖demo
阿新 • • 發佈:2018-11-02
之前版本的改進,增加了ecc加密,PoW機制等,並對一個使用者生成10對祕鑰實現匿名。
package main import ( "crypto/ecdsa" "crypto/elliptic" "crypto/rand" "crypto/sha256" "encoding/hex" "fmt" "math/big" "strconv" "time" ) type Block struct { //PoW string timeStamp string meetingTime string phoneNumber string lockNumber string meetingName string roomNumber string hashcode string eccHashcode []byte prk *ecdsa.PrivateKey puk ecdsa.PublicKey } func calculateHashcode(b Block) string { data := b.meetingTime + b.phoneNumber + b.lockNumber + b.meetingName + b.roomNumber nonce := 1 var str string var check string pass := false var dif int = 6 for t := 0; ; t++ { str = "" check = "" check = data + strconv.Itoa(nonce) h := sha256.New() h.Write([]byte(check)) hashed := h.Sum(nil) str = hex.EncodeToString(hashed) for i := 0; i < dif; i++ { if str[i] != '0' { nonce++ break } if i == dif-1 { pass = true } } if pass == true { return str } } } func getKey() (*ecdsa.PrivateKey, error) { prk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) return prk, err } func eccSign(data []byte, prk *ecdsa.PrivateKey) ([]byte, error) { r, s, err := ecdsa.Sign(rand.Reader, prk, data) if err != nil { return nil, err } params := prk.Curve.Params() curveOrderByteSize := params.P.BitLen() / 8 rBytes, sBytes := r.Bytes(), s.Bytes() signature := make([]byte, curveOrderByteSize*2) copy(signature[curveOrderByteSize-len(rBytes):], rBytes) copy(signature[curveOrderByteSize*2-len(sBytes):], sBytes) return signature, nil } func eccVerify(data, signature []byte, puk *ecdsa.PublicKey) bool { curveOrderByteSize := puk.Curve.Params().P.BitLen() / 8 r, s := new(big.Int), new(big.Int) r.SetBytes(signature[:curveOrderByteSize]) s.SetBytes(signature[curveOrderByteSize:]) return ecdsa.Verify(puk, data, r, s) } func setBlock(mt, pn, ln, mn, rn string) Block { var newBlock Block t := time.Now() newBlock.timeStamp = t.String() //newBlock.PoW = proofOfWork(t.UnixNano()) newBlock.meetingTime = mt newBlock.phoneNumber = pn newBlock.lockNumber = ln newBlock.meetingName = mn newBlock.roomNumber = rn newBlock.hashcode = calculateHashcode(newBlock) prk, err := getKey() if err != nil { panic(err) } newBlock.prk = prk newBlock.puk = prk.PublicKey eccHashcode, err := eccSign([]byte(newBlock.hashcode), newBlock.prk) if err != nil { panic(err) } newBlock.eccHashcode = eccHashcode return newBlock } func checkBlock(Block Block) bool { if calculateHashcode(Block) != Block.hashcode { fmt.Println("hash error") return false } if Block.timeStamp > "2018-10-17" { fmt.Println(" time error") return false } if eccVerify([]byte(Block.hashcode), Block.eccHashcode, &Block.puk) == false { fmt.Println("ecc error") return false } return true } func main() { var mt = "20181111" var pn = "18811881188" var ln = "001" var mn = "importantmeeting" var rn = "216" //var bc = setBlock(mt, pn, ln, mn, rn) var bc [10]Block for i := 0; i < 10; i++ { bc[i] = setBlock(mt, pn, ln, mn, rn) fmt.Println("{") fmt.Println(" user phonenumber:", bc[i].phoneNumber) fmt.Println(" lock number:", bc[i].lockNumber) fmt.Println(" meeting name:", bc[i].meetingName) fmt.Println(" room number:", bc[i].roomNumber) fmt.Println(" hash:", bc[i].hashcode) fmt.Println(" eccCrypto", hex.EncodeToString(bc[i].eccHashcode)) fmt.Println(" check:", checkBlock(bc[i])) fmt.Println("}") } // fmt.Println(len(bc.hashcode)) // fmt.Println(len(hex.EncodeToString(bc.eccHashcode))) }