//intenal, may fail //may return nil func _pubkeyFromSeckey(seckey []byte) []byte { if len(seckey) != 32 { log.Panic("seckey length invalid") } if secp.SeckeyIsValid(seckey) != 1 { log.Panic("always ensure seckey is valid") return nil } var pubkey []byte = secp.GeneratePublicKey(seckey) //always returns true if pubkey == nil { log.Panic("ERROR: impossible, secp.BaseMultiply always returns true") return nil } if len(pubkey) != 33 { log.Panic("ERROR: impossible, invalid pubkey length") } if ret := secp.PubkeyIsValid(pubkey); ret != 1 { log.Panic("ERROR: pubkey invald, ret=%s", ret) return nil } if _VerifyPubkey(pubkey) != 1 { log.Panic("ERROR: pubkey verification failed, for deterministic") return nil } return pubkey }
//Rename ChkSeckeyValidity func VerifySeckey(seckey []byte) int { if len(seckey) != 32 { return -1 } //does conversion internally if less than order of curve if secp.SeckeyIsValid(seckey) != 1 { return -2 } //seckey is just 32 bit integer //assume all seckey are valid //no. must be less than order of curve //note: converts internally return 1 }
//generates deterministic keypair with weak SHA256 hash of seed //internal use only //be extremely careful with golang slice semantics func generateDeterministicKeyPair(seed []byte) ([]byte, []byte) { if seed == nil { log.Panic() } if len(seed) != 32 { log.Panic() } const seckey_len = 32 var seckey []byte = make([]byte, seckey_len) new_seckey: seed = SumSHA256(seed[0:32]) copy(seckey[0:32], seed[0:32]) if bytes.Equal(seckey, seed) == false { log.Panic() } if secp.SeckeyIsValid(seckey) != 1 { log.Printf("generateDeterministicKeyPair, secp.SeckeyIsValid fail") goto new_seckey //regen } var pubkey []byte = secp.GeneratePublicKey(seckey) if pubkey == nil { log.Panic("ERROR: impossible, secp.BaseMultiply always returns true") goto new_seckey } if len(pubkey) != 33 { log.Panic("ERROR: impossible, pubkey length wrong") } if ret := secp.PubkeyIsValid(pubkey); ret != 1 { log.Panic("ERROR: pubkey invalid, ret=%i", ret) } if ret := VerifyPubkey(pubkey); ret != 1 { log.Printf("seckey= %s", hex.EncodeToString(seckey)) log.Printf("pubkey= %s", hex.EncodeToString(pubkey)) log.Panic("ERROR: pubkey is invalid, for deterministic. ret=%i", ret) goto new_seckey } return pubkey, seckey }
//Rename SignHash func _Sign(msg []byte, seckey []byte) []byte { if len(seckey) != 32 { log.Panic("Sign, Invalid seckey length") } if secp.SeckeyIsValid(seckey) != 1 { log.Panic("Attempting to sign with invalid seckey") } if msg == nil { log.Panic("Sign, message nil") } var nonce []byte = RandByte(32) var sig []byte = make([]byte, 65) var recid int var cSig secp.Signature var seckey1 secp.Number var msg1 secp.Number var nonce1 secp.Number seckey1.SetBytes(seckey) msg1.SetBytes(msg) nonce1.SetBytes(nonce) ret := cSig.Sign(&seckey1, &msg1, &nonce1, &recid) if ret != 1 { log.Panic("Secp25k1-go, _Sign, signature operation failed") } sig_bytes := cSig.Bytes() for i := 0; i < 64; i++ { sig[i] = sig_bytes[i] } if len(sig_bytes) != 64 { log.Fatal("Invalid signature byte count: %s", len(sig_bytes)) } sig[64] = byte(int(recid)) if int(recid) > 4 { log.Panic() } return sig }
func _GenerateKeyPair() ([]byte, []byte) { const seckey_len = 32 new_seckey: var seckey []byte = RandByte(seckey_len) if secp.SeckeyIsValid(seckey) != 1 { goto new_seckey //regen } pubkey := _pubkeyFromSeckey(seckey) if pubkey == nil { log.Panic("IMPOSSIBLE: pubkey invalid from valid seckey") goto new_seckey } if ret := secp.PubkeyIsValid(pubkey); ret != 1 { log.Panic("ERROR: Pubkey invalid, ret=%s", ret) goto new_seckey } return pubkey, seckey }