//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 ret := VerifyPubkey(pubkey); ret != 1 { log.Printf("seckey= %s", hex.EncodeToString(seckey)) log.Printf("pubkey= %s", hex.EncodeToString(pubkey)) log.Panic("ERROR: pubkey verification failed, for deterministic. ret=%d", ret) return nil } return pubkey }
//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 }