MetacoSA / NBitcoin

Comprehensive Bitcoin library for the .NET framework.
MIT License
1.89k stars 849 forks source link

Re-target to PCL #8

Closed fonix232 closed 9 years ago

fonix232 commented 10 years ago

NBitcoin currently only targets regular .Net 4.5 - which is great for desktop apps and so, but completely useless for the new WinRT platform.

It would be great if the project would be re-targeted for Windows Universal apps PCL, even as a separate branch, it would make it easier to finally have a wallet app on WP/W8.1.

NicolasDorier commented 10 years ago

I already did it for one customer, for a kick ass commercial wallet app that will release soon. (Big announcement ahead) I am in a delicate position, because they paid for it, so I can't (and don't want to) release what I have done in open source. However, I definitively want to permit that on the middle and long term for NBitcoin.

So I can help whoever wants to try to do it. The workload for porting 80% of NBitcoin (tests included) is about 2 or 3 days. Here are the things to do in order to achieve the port :

  1. References BouncyCastle sources directly instead of nuget package. (but it means we will stop benefiting from their security update, and that people will need to trust my own fork of it)
  2. Removing any source in BouncyCastle that is not used by NBitcoin.
  3. Doing the same for NBitcoin,

Be careful, NBitcoin depends on Windows Crypto API for some stuff, so you'll have to use bouncy castle instead. Also, I depend on some place on secure RNG, but RNG with high enough entropy is always plateform specific.

I will help to communicate on a PCL port, can help if there is question, and would include it in Nuget, but I can't develop it myself for now.

fonix232 commented 10 years ago

I see. I agree that if it has been done commercially, you should not release the code - it's been paid for, so it's not yours, per say, to release.

Thing is, I do not believe I'm on a level that I could do the porting, and given I have a day job, I could not focus on learning and doing all the work, even with guidance. Though I might try.

About the issues:

  1. I tried re-targeting to BouncyCastle-PCL. Yes, it's not a regularly updated project, but until the moment BC decides to compile a windows8.1-wp8 library (either Silverlight or WinRT), we're stuck with either manual compile or that.
  2. So you'd heavily modify an existing library to bring down the library size? IMHO that is the worst thing you can do in programming (apart from not commenting your code) for usability. Depending on a truncated library is never a good idea in my opinion.
  3. Does a mobile version of NBitcoin truly have to be limited? Yes, I understand that it is for resource saving, and also many functions will be rarely called upon (I can't imagine someone using a phone for cold storage, for example), but a fully fledged library would be better to use.

AFAIK WinRT includes the Crypto API, to a limited extent (though differently than WPF/desktop apps).

RNG can be easily generated if you use sensor data (magnetic, light, etc.). Just spin a pseudo-RN from the platform Random(), and use that value to decide which sensor data to use for the next part of the random key.

NicolasDorier commented 10 years ago
  1. I don't like this solution either, because it means we'll be out of sync with the repo of BouncyCaslte.
  2. It does not have to be limited, however the Time To Develop / Utility ratio for the last % become very low.

Porting the whole lib is considerably harder than a subset of it, so if any plan to port should be made, I think it should be released incrementally through several updates. The last % can be a real headache.

For the RNG, sadly you have the same problem, because there is no unified lib accross devices to access magnetic, light and the like. It means that your solution is harder than just creating an interface around the RNG whose implementation would be plateform specific.

I keep the issue open until I or someone else develop a portable lib.

fonix232 commented 10 years ago

Actually, the RNG part can be solved with Win8's Sensor API. But I have a better idea for RNGs - use the camera! No need to take a picture, just run the preview for a few seconds, and use either pre-set or randomized areas (say, generate four pseudo-random numbers, from 0 to max img width and 0 to max img height of camera, then take the area pointed out by x1,y1 and x2,y2; and use the area for random numbers. As most of the cameras have pretty huge amount of noise compared to e.g. DSLRs, the noise can be random enough for truly random numbers).

And indeed the darn BouncyCastle part is the biggest headache. Though as I said, the BouncyCastle-PCL package solves that issue too, and if the library only targets WinRT/WP8.1 Universal, the PCL is usable. Not so sure about WP8 Silverlight.

fonix232 commented 10 years ago

Nicolas, is there any news about that commercial wallet app you mentioned? It's been almost two months and I haven't heard any big news yet :\

NicolasDorier commented 10 years ago

Hey, yes it will be out soon. However, I can't tell you because of non disclosure. I give the link to this thread to my customer, so he can reply directly if he wants to. :)

fonix232 commented 10 years ago

Hey Nicolas... Is your customer still set on releasing their app? Maybe they should start a marketing campaign or something, because there are still no news, and honestly, them licensing your work so far only hindered the possible efforts of having an open source client.

NicolasDorier commented 10 years ago

Fonix, I think I will soon try to work on that. I created a portable library for them, but the approach I will take is 1 project per plateform with shared csproj. This is different and I will not be able to count on what I did for them for helping me.

I want to use the "Bait and Switch" trick, but without having to write dummy implementations. (Time waste) http://log.paulbetts.org/the-bait-and-switch-pcl-trick/

Also, the time I release that, their application should be shipped. However, I'm missing time these days, so any tip or help is always welcomed ;)

Also, with a recent release I cutted the dependency on bouncycastle, so the port is easier. (I did it for performance reason actually)

CheekyGhost commented 10 years ago

Hello, I think you should release the PCL build because this will spark the growth of Bitcoin on modern platforms (Modern in the sense of the MSFT Modern Shell)

NicolasDorier commented 10 years ago

the shame is that mobile and modern shell does not support classical sockets. It makes the connecting to the network unportable at all. But still lots of thing can be ported. The port I want to do will include android, ios, wp81, modern, and also MF (Micro Framework).

I expect people doing great stuff with gadgeteer and netduino ! :)

CheekyGhost commented 9 years ago

Yes I do understand what you mean but I thought you had previously accomplished this? Definitely at the moment the discrepancy between sockets on WinRT and Windows Phone vs .NET does diminish this within a PCL. I in fact have a version of Bitcoinsharp which I've modified to be PCL compliant but it only generates Bitcoin addresses (I added the functionality of compressed pub key addresses as it was not supporting) but yea I had to strip the guts out of it, anything that relied on networking had to go so no transactions etc. I am thinking the future of mobile wallets involes key management on the client, with Blockchain parsing etc in the cloud. My vision is to run a service in the cloud that parses the blockchain, looks for transactions etc then send notifications back to apps on mobile devices. What are your thought?

NicolasDorier commented 9 years ago

I agree. And yes I accomplished this for a customer which is the reason why I did not open sourced it, I basically forked NBitcoin for them. It was not very complicated.

But since their wallet will soon release, I will start working on making NBitcoin on all plateform and distributable by nuget. The first step will not to do the portable lib, but specific lib for each plateform. Then once I find the common ground between them all, I will add the portable. This way, we will have both of the best : portable with only core things shared, but specific lib with more stuff depending on support of networking and crypto lib

CheekyGhost commented 9 years ago

Ah yes so did you create a solution for someone, like I have with just the key generation etc in a PCL? So you haven't got Block processing etc in a PCL is that right?

NicolasDorier commented 9 years ago

I did, block processing does not depends on anything related to windows. The only stuff I did not put in portable was :

The rest was smooth to port.

CheekyGhost commented 9 years ago

Nice work! Might I suggest to you to use SecureRandom in BouncyCastle as a PCL friendly method of getting crypto random bytes? I see you know about the PCL version of BouncyCastle, but then I swe in your latest code you have gone away from using BC. Any reason for the shift away from BC?

NicolasDorier commented 9 years ago

I am glad to say that I ported the code to Portable today. Not yet distributed in Nuget, I will do that tomorrow. The test suite is also ported.

Yes, there is a reason to shift away from BC : their nuget package is from 2011, and ECC operations are 100 times more perfomant on their current master (that's not a typo), but they won't release nuget package even if I pray for it and give them the freaking powershell script to do it easily.

I have not tried the PCL version, but being not from the BC team, it is surely behind.

Also, I stripped a lot from BC, it made the port easier. "Portable" is a complicated topic, it all depends on what profile the "portable" target, I prefer to have the flexibility to change the code.

My profile is "111", this is Xamarin.iOS, Xamarin.Android, WP 8.1, Windows 8, .NET 4.5. By the way, their SecureRandom depends on an underlying RNG (Windows one), so I can't use it as is. For my unit tests, I created an "UnsecureRandom". However, in release version, you will need to provide your own one with IRandom RandomUtils.Random property, or you'll get an exception.

I intend to make plateform specific assemblies later, so I can hard code the RNG depending on the plateform. The windows specific project use already the RngCryptoServiceProvider of the plateform by default.

CheekyGhost commented 9 years ago

Congrats!!!

Yes I agree with you that the PCL BouncyCastle DLL will be behind and I imagine will have the performance issue you mention. Although if you are just generating the odd key here and there I don't think it is too much of an issue? Certainly if you want to do lots of keys in bulk yes.

Ah I see so your PCL is in fact a even more unified version that does Android and iOS in Xamarin. My PCLs are all for the windows platform that is why I have had success with SecureRandom. I see you are creating PCLs for Android and iOS too! That's actually really awesome!

NicolasDorier commented 9 years ago

The performance issue is not on key generation, but on signature checking and generation, which is a big problem when you are doing a web service that lots of customer will be using, you don't want the CPU to be exhausted.

I will release on nuget tomorrow, please try it then on other windows plateform. Currently the PCL use BC for crypto operations, but when I will do the plateform specific versions, Windows phone and tablets will use the crypto api of windows transparently. (Thanks to the "bait and switch" PCL trick)

CheekyGhost commented 9 years ago

Ah yes I get you.

Yes awesome man!!!

NicolasDorier commented 9 years ago

I have the pleasure to consider this issue as closed : http://www.reddit.com/r/Bitcoin/comments/2ont6t/nbitcoin_mac_ios_android_windows_phone_81_windows/