Skip to content

Initial implementation. #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 4, 2022
Merged

Conversation

sjrd
Copy link
Member

@sjrd sjrd commented Mar 30, 2022

Goes together with scala-js/scala-js#4659

Draft because the CI script mentions my fork of scala-js/scala-js. We'll need it to change that once scala-js/scala-js#4659 is merged.

But otherwise it's ready to review.

@sjrd sjrd requested a review from gzm0 March 30, 2022 12:26
@sjrd
Copy link
Member Author

sjrd commented Mar 30, 2022

Copy link

@gzm0 gzm0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Higher level comment:

There seems to be a lot of duplication with the real implementation. Does it make sense to put them into a single repository and have two sbt projects in it?

The most likely changes I see to this code are:

  • JDK interface changes.
  • Adjustments to the crypto API detection.

Both of which are shared. So the effort to keep them in sync will be much higher if we put these into separate repos.

build.sbt Outdated

jsEnvKind.value match {
case NodeJS =>
old
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider not relying on the default.

// setSeed has no effect
override def setSeed(x: Long): Unit = ()

override def nextBytes(bytes: Array[Byte]): Unit = {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ugh... What is happening here...

Looking at the documentation of Random, you're not allowed to do this: The documentation of next states:

Subclasses should override this, as this is used by all other methods.

Since SecureRandom is not final, a subclass may override next and expect nextBytes to use its overridden implementation.

However, SecureRandom provides its own nextBytes method...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

next is final in SecureRandom. 😉

private val getRandomValuesFun = SecureRandom.getRandomValuesFun

// setSeed has no effect
override def setSeed(x: Long): Unit = ()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is odd. Reading the documentation, I would expect the following to end up being deterministic:

val x = new SecureRandom
x.setSeed(0)  // seeds x, doc says x will be seeded lazily
x.nextInt()

However, experimentally, it seems that the result is not deterministic. Hence, this implementation is OK.

Maybe comment on that?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add a comment.

The idea is that, for cryptographically secure RNG, giving a seed can only ever increase the entropy. It is never allowed to decrease it. Given that we don't have access to an API to strengthen the entropy of the underlying RNG, it's fine to ignore it instead.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that makes sense as soon as the SecureRandom is seeded. But the documentation is very clear that seeding only happens once a random value is actually required. But yes, maybe the term "seeing" here is a bit overloaded.

random.nextBytes(buffer)

// the likelihood of this failing should be one in 4 billion
assertTrue("nextBytes() must fill the provided buffer", buffer.count(_ == 0) < 4)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it worth doing this check? Feels like the difference check should be enough.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The difference check does not protect against accidentally filling only a prefix of the array, for example. This ensures that all bytes are covered.

}

override protected final def next(numBits: Int): Int = {
if (numBits == 0) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While you're here, protect against negative numBits as well? (OTOH it's protected, so maybe OK).

@sjrd
Copy link
Member Author

sjrd commented Apr 2, 2022

There seems to be a lot of duplication with the real implementation. Does it make sense to put them into a single repository and have two sbt projects in it?

I'm... not sure. It would make sense if we intend to keep developing and evolving both in the foreseeable future. But I'm very much hoping that we will be able to publish the fake one once, as a stop gap migration measure, and then leave it to die out. In that scenario, I think it makes more sense to keep them separate.

@gzm0
Copy link

gzm0 commented Apr 3, 2022

In that scenario, I think it makes more sense to keep them separate.

OK. Fair enough. Let's gamble on that, and if need be, we can still merge the repos in the future.

@sjrd sjrd force-pushed the initial-implementation branch from 36c2666 to a91e27b Compare April 4, 2022 08:44
@sjrd sjrd marked this pull request as ready for review April 4, 2022 09:06
@sjrd sjrd requested a review from gzm0 April 4, 2022 09:06
@sjrd
Copy link
Member Author

sjrd commented Apr 4, 2022

I think I have addressed all the comments in this one. I have also updated to use the latest commit from scala-js/scala-js.

@sjrd sjrd force-pushed the initial-implementation branch from a91e27b to a0aafdb Compare April 4, 2022 14:55
@sjrd
Copy link
Member Author

sjrd commented Apr 4, 2022

Updated to Scala.js 1.10.0.
Green CI build at https://github.com/sjrd/scala-js-fake-insecure-java-securerandom/actions/runs/2090667917

@sjrd sjrd merged commit b5ddd59 into scala-js:main Apr 4, 2022
@sjrd sjrd deleted the initial-implementation branch April 4, 2022 15:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants