resolves #2 - use window.crypto.getRandomValues(), otherwise fallback to Math.random()