func (ks keyStorePassphrase) StoreKey(key *Key, auth string) (err error) { authArray := []byte(auth) salt := randentropy.GetEntropyCSPRNG(32) derivedKey, err := scrypt.Key(authArray, salt, ks.scryptN, ks.scryptR, ks.scryptP, ks.scryptDKLen) if err != nil { return err } encryptKey := derivedKey[:16] keyBytes := FromECDSA(key.PrivateKey) iv := randentropy.GetEntropyCSPRNG(aes.BlockSize) // 16 cipherText, err := aesCTRXOR(encryptKey, keyBytes, iv) if err != nil { return err } mac := Sha3(derivedKey[16:32], cipherText) scryptParamsJSON := make(map[string]interface{}, 5) scryptParamsJSON["n"] = ks.scryptN scryptParamsJSON["r"] = ks.scryptR scryptParamsJSON["p"] = ks.scryptP scryptParamsJSON["dklen"] = ks.scryptDKLen scryptParamsJSON["salt"] = hex.EncodeToString(salt) cipherParamsJSON := cipherparamsJSON{ IV: hex.EncodeToString(iv), } cryptoStruct := cryptoJSON{ Cipher: "aes-128-ctr", CipherText: hex.EncodeToString(cipherText), CipherParams: cipherParamsJSON, KDF: "scrypt", KDFParams: scryptParamsJSON, MAC: hex.EncodeToString(mac), } encryptedKeyJSONV3 := encryptedKeyJSONV3{ hex.EncodeToString(key.Address[:]), cryptoStruct, key.Id.String(), version, } keyJSON, err := json.Marshal(encryptedKeyJSONV3) if err != nil { return err } return writeKeyFile(key.Address, ks.keysDirPath, keyJSON) }
func GenerateKeyPair() ([]byte, []byte) { var seckey []byte = randentropy.GetEntropyCSPRNG(32) var seckey_ptr *C.uchar = (*C.uchar)(unsafe.Pointer(&seckey[0])) var pubkey64 []byte = make([]byte, 64) // secp256k1_pubkey var pubkey65 []byte = make([]byte, 65) // 65 byte uncompressed pubkey pubkey64_ptr := (*C.secp256k1_pubkey)(unsafe.Pointer(&pubkey64[0])) pubkey65_ptr := (*C.uchar)(unsafe.Pointer(&pubkey65[0])) ret := C.secp256k1_ec_pubkey_create( context, pubkey64_ptr, seckey_ptr, ) if ret != C.int(1) { return GenerateKeyPair() // invalid secret, try again } var output_len C.size_t C.secp256k1_ec_pubkey_serialize( // always returns 1 context, pubkey65_ptr, &output_len, pubkey64_ptr, 0, // SECP256K1_EC_COMPRESSED ) return pubkey65, seckey }
func Sign(msg []byte, seckey []byte) ([]byte, error) { msg_ptr := (*C.uchar)(unsafe.Pointer(&msg[0])) seckey_ptr := (*C.uchar)(unsafe.Pointer(&seckey[0])) sig := make([]byte, 65) sig_ptr := (*C.secp256k1_ecdsa_recoverable_signature)(unsafe.Pointer(&sig[0])) nonce := randentropy.GetEntropyCSPRNG(32) ndata_ptr := unsafe.Pointer(&nonce[0]) noncefp_ptr := &(*C.secp256k1_nonce_function_default) if C.secp256k1_ec_seckey_verify(context, seckey_ptr) != C.int(1) { return nil, errors.New("Invalid secret key") } ret := C.secp256k1_ecdsa_sign_recoverable( context, sig_ptr, msg_ptr, seckey_ptr, noncefp_ptr, ndata_ptr, ) if ret == C.int(0) { return Sign(msg, seckey) //invalid secret, try again } sig_serialized := make([]byte, 65) sig_serialized_ptr := (*C.uchar)(unsafe.Pointer(&sig_serialized[0])) var recid C.int C.secp256k1_ecdsa_recoverable_signature_serialize_compact( context, sig_serialized_ptr, // 64 byte compact signature &recid, sig_ptr, // 65 byte "recoverable" signature ) sig_serialized[64] = byte(int(recid)) // add back recid to get 65 bytes sig return sig_serialized, nil }